back to project page

GRAPHIX II Disassembly

                   ********************************************************************************
                   * Caverns of Freitag, by David Shapiro                                         *
                   * Copyright 1982                                                               *
                   *                                                                              *
                   * Disassembly of "GRAPHIX II".                                                 *
                   ********************************************************************************
                   * The various subroutines are invoked from CF (Applesoft) by way of AMPER, and *
                   * from CF.OBJ.                                                                 *
                   ********************************************************************************
                   * Disassembly by Andy McFadden, using 6502bench SourceGen v1.5.                *
                   * Last updated 2020/01/26                                                      *
                   ********************************************************************************
                   ARG_DIST        .eq     $19               ;LINESET distance
                   ARG_DRAW_MODE   .eq     $1c               ;0=draw, 1=erase, 2=invert
                   ARG_ITEM_INDEX  .eq     $1e               ;LINESET/CHARSET item index
                   ARG_COLOR       .eq     $1f               ;0=green, 1=orange, 2=purple, 3=blue
                   ARG_EXT_PTR     .eq     $e8    {addr/2}   ;pointer to external data
                   ARG_X0          .eq     $f9    {addr/2}   ;X coord #0 (0-255 or 0-139)
                   ARG_Y0          .eq     $fb               ;Y coord #0 (0-191)
                   ARG_X1          .eq     $fc    {addr/2}   ;X coord #1 (0-255 or 0-139)
                   ARG_Y1          .eq     $fe               ;Y coord #1 (0-191)
                   ARG_FF          .eq     $ff               ;shape fill flag -or- CLR color
                   HIRES_PAGE_1    .eq     $2000  {addr/8192}
                   TXTCLR          .eq     $c050             ;RW display graphics
                   TXTSET          .eq     $c051             ;RW display text
                   MIXCLR          .eq     $c052             ;RW display full screen
                   MIXSET          .eq     $c053             ;RW display split screen
                   TXTPAGE1        .eq     $c054             ;RW display page 1
                   TXTPAGE2        .eq     $c055             ;RW display page 2 (or read/write aux mem)
                   HIRES           .eq     $c057             ;RW display hi-res graphics
                   MON_BELL1       .eq     $fbdd             ;sound bell regardless of output device

                                   .org    $0800
0800: 4c 60 08     DOT             jmp     HandleDOT

0803: 4c 73 08                     jmp     HandleDOT_1

0806: 4c ac 08     CHKDOT          jmp     HandleCHKDOT

0809: 4c d0 08     LINE            jmp     HandleLINE

080c: 4c 6b 0a     LINESET         jmp     HandleLINESET     ;used for wizard Zap attack

080f: 4c 29 0c     CLR             jmp     HandleCLR

0812: 4c c0 0c     SCFLIP          jmp     HandleSCFLIP

0815: 4c ea 0d     HISCROLL        jmp     HandleHISCROLL

0818: 4c 1c 0e     BOX             jmp     HandleBOX

081b: 4c db 0e     SWITCHC         jmp     HandleSWITCHC

081e: 4c f3 0e     CHARSET         jmp     HandleCHARSET     ;line 14000 (arrow animation) and 15000 (hit)

0821: 4c 96 0f     BDRW            jmp     HandleBDRW        ;draws tiles for mode 1 display

0824: 4c f3 0f     CIRCLE          jmp     HandleCIRCLE

0827: 4c 78 11     PENGUIN         jmp     HandlePENGUIN

082a: 4c 8a 11     CDOT            jmp     HandleCDOT

082d: 4c 9d 11                     jmp     HandleCDOT_1

0830: 4c e7 11     CLINE           jmp     HandleCLINE

0833: 4c 19 13     CBOX            jmp     HandleCBOX

0836: 4c 9f 13     CCHARSET        jmp     HandleCCHARSET

                   ********************************************************************************
                   * Handle HIRES                                                                 *
                   *                                                                              *
                   * Enable hi-res graphics.  Does not touch mixed-mode flag.                     *
                   ********************************************************************************
0839: 2c 57 c0     HIRES_          bit     HIRES
083c: 2c 50 c0                     bit     TXTCLR
083f: 60                           rts

                   ********************************************************************************
                   * Handle HROFF                                                                 *
                   *                                                                              *
                   * Switches to text mode.                                                       *
                   ********************************************************************************
0840: 2c 51 c0     HROFF           bit     TXTSET
0843: 60                           rts

                   ********************************************************************************
                   * Handle WINDOW                                                                *
                   *                                                                              *
                   * Enable mixed mode (4 lines of text at bottom).                               *
                   ********************************************************************************
0844: 2c 53 c0     WINDOW          bit     MIXSET
0847: 60                           rts

                   ********************************************************************************
                   * Handle WNDOFF                                                                *
                   *                                                                              *
                   * Disable mixed mode (full-screen graphics).                                   *
                   ********************************************************************************
0848: 2c 52 c0     WNDOFF          bit     MIXCLR
084b: 60                           rts

                   ********************************************************************************
                   * Handle DRWPG1                                                                *
                   *                                                                              *
                   * Select hi-res page 1 for drawing.                                            *
                   ********************************************************************************
084c: a9 20        DRWPG1          lda     #$20
084e: 8d 85 14                     sta     hpage
0851: 60                           rts

                   ********************************************************************************
                   * Handle DRWPG2                                                                *
                   *                                                                              *
                   * Select hi-res page 2 for drawing.                                            *
                   ********************************************************************************
0852: a9 40        DRWPG2          lda     #$40
0854: 8d 85 14                     sta     hpage
0857: 60                           rts

                   ********************************************************************************
                   * Handle DISPPG1                                                               *
                   *                                                                              *
                   * Set display to page 1.                                                       *
                   ********************************************************************************
0858: 2c 54 c0     DISPPG1         bit     TXTPAGE1
085b: 60                           rts

                   ********************************************************************************
                   * Handle DISPPG2                                                               *
                   *                                                                              *
                   * Set display to page 2.                                                       *
                   ********************************************************************************
085c: 2c 55 c0     DISPPG2         bit     TXTPAGE2
085f: 60                           rts

                   ********************************************************************************
                   * Handle DOT,x0,y0,drawMode                                                    *
                   *                                                                              *
                   * On entry:                                                                    *
                   *   $F9/FA/FB: x0,y0                                                           *
                   *   $1C: drawMode (0=draw, 1=erase, 2=invert)                                  *
                   ********************************************************************************
                   • Clear variables
                   ]hptr           .var    $06    {addr/2}

0860: a4 fb        HandleDOT       ldy     ARG_Y0            ;range check Y coord
0862: c9 c0                        cmp     #192              ;off end of screen?
0864: b0 3b                        bcs     :Done             ;yup, bail
0866: b9 b6 17                     lda     hr_addr_lo,y
0869: 85 06                        sta     ]hptr
086b: b9 76 18                     lda     hr_addr_hi,y
086e: 0d 85 14                     ora     hpage
0871: 85 07                        sta     ]hptr+1
                   ; Call here if the Y coordinate hasn't changed since the previous call.
0873: a6 fa        HandleDOT_1     ldx     ARG_X0+1          ;high byte of X coord is zero?
0875: f0 14                        beq     L088B             ;yup, keep going
0877: a6 f9                        ldx     ARG_X0
0879: e0 18                        cpx     #24               ;range check X coord (280 - 256 = 24)
087b: b0 24                        bcs     :Done
087d: a4 fa                        ldy     ARG_X0+1          ;it's not zero; is it one?
087f: 88                           dey
0880: d0 1f                        bne     :Done
0882: bd 36 1a                     lda     div7_hi,x
0885: a8                           tay
0886: bd 4e 1b                     lda     mod7_hi,x
0889: d0 09                        bne     :Cont             ;(always)
088b: a6 f9        L088B           ldx     ARG_X0
088d: bd 36 19                     lda     div7_lo,x
0890: a8                           tay
0891: bd 4e 1a                     lda     mod7_lo,x
0894: a6 1c        :Cont           ldx     ARG_DRAW_MODE     ;draw mode flag
0896: f0 0a                        beq     L08A2             ;=0, use ORA ("draw")
0898: ca                           dex
0899: d0 0c                        bne     L08A7             ;=2, use EOR ("invert")
089b: 49 7f                        eor     #$7f              ;=1, invert and AND ("erase")
089d: 31 06                        and     (]hptr),y
089f: 91 06                        sta     (]hptr),y
08a1: 60           :Done           rts

08a2: 11 06        L08A2           ora     (]hptr),y
08a4: 91 06                        sta     (]hptr),y
08a6: 60                           rts

08a7: 51 06        L08A7           eor     (]hptr),y
08a9: 91 06                        sta     (]hptr),y
08ab: 60                           rts

                   ********************************************************************************
                   * Handle CHKDOT,X0,X0                                                          *
                   *                                                                              *
                   * On entry:                                                                    *
                   *   $F9/FA/FB: x0,y0 (0-279,0-191)                                             *
                   *                                                                              *
                   * On exit:                                                                     *
                   *   $FF: $00 if pixels is clear, $01 if pixel is set                           *
                   *                                                                              *
                   * NOTE: behaves incorrectly X values >= 256.                                   *
                   * NOTE: if SWITCHC has been called, this will incorrectly report a set pixel   *
                   * if the screen byte is $80 (black1).                                          *
                   ********************************************************************************
                   ]result         .var    $ff    {addr/1}

08ac: a4 fb        HandleCHKDOT    ldy     ARG_Y0            ;set up hi-res address
08ae: b9 b6 17                     lda     hr_addr_lo,y
08b1: 85 06                        sta     ]hptr
08b3: b9 76 18                     lda     hr_addr_hi,y
08b6: 0d 85 14                     ora     hpage
08b9: 85 07                        sta     ]hptr+1
08bb: a6 f9                        ldx     ARG_X0            ;get X offset; note we ignore high byte
08bd: bd 36 19                     lda     div7_lo,x
08c0: a8                           tay
08c1: bd 4e 1a                     lda     mod7_lo,x         ;get bit pattern
08c4: 31 06                        and     (]hptr),y
08c6: d0 03                        bne     :PixelSet
08c8: 85 ff                        sta     ]result
08ca: 60                           rts

08cb: a9 01        :PixelSet       lda     #$01
08cd: 85 ff                        sta     ]result
08cf: 60                           rts

                   ********************************************************************************
                   * Handle LINE,X0,Y0,X1,Y1,drawMode                                             *
                   *                                                                              *
                   * On entry:                                                                    *
                   *   $F9/FA/FB: x0,y0                                                           *
                   *   $FC/FD/FE: x1,y1                                                           *
                   *   $1C: drawMode (0=draw, 1=erase, 2=invert)                                  *
                   *                                                                              *
                   * On exit:                                                                     *
                   *   $F9/FA/FB holds 2nd coordinate (so you can chain calls)                    *
                   ********************************************************************************
                   • Clear variables
                   ]move_dir       .var    $08    {addr/1}   ;$01 or $ff
                   ]move_dir_hi    .var    $09    {addr/1}
                   ]tmp_xl         .var    $19    {addr/1}
                   ]tmp_xh         .var    $1a    {addr/1}
                   ]count          .var    $1b    {addr/1}
                   ]delta_xl       .var    $1e    {addr/1}
                   ]delta_xh       .var    $1f    {addr/1}
                   ]delta_y        .var    $ff    {addr/1}

08d0: a5 fc        HandleLINE      lda     ARG_X1            ;save X1,Y1; this will be restored to X0,Y0 at the end
08d2: 8d 56 14                     sta     saved_xlo
08d5: a5 fd                        lda     ARG_X1+1
08d7: 8d 57 14                     sta     saved_xhi
08da: a5 fe                        lda     ARG_Y1
08dc: 8d 58 14                     sta     saved_y
08df: a5 1f                        lda     ]delta_xh         ;save $1F; will be restored before exit
08e1: 8d 69 14                     sta     saved_1f
08e4: a5 fb                        lda     ARG_Y0            ;compute deltaY
08e6: 38                           sec
08e7: e5 fe                        sbc     ARG_Y1
08e9: b0 05                        bcs     L08F0             ;still positive, good
08eb: a5 fe                        lda     ARG_Y1            ;subtract the other way
08ed: 38                           sec
08ee: e5 fb                        sbc     ARG_Y0
08f0: 85 ff        L08F0           sta     ]delta_y          ;FF=deltaY
08f2: a5 fc        :ComputeDeltaX  lda     ARG_X1            ;compute deltaX
08f4: 38                           sec
08f5: e5 f9                        sbc     ARG_X0
08f7: 85 1e                        sta     ]delta_xl         ;1E=deltaX low
08f9: a5 fd                        lda     ARG_X1+1          ;now do the high part
08fb: e5 fa                        sbc     ARG_X0+1
08fd: 10 06                        bpl     L0905             ;positive, good
08ff: 20 52 0a                     jsr     SwapCoords        ;flip so we're always X0 < X1
0902: 4c f2 08                     jmp     :ComputeDeltaX    ;redo the delta X computation

0905: 85 1f        L0905           sta     ]delta_xh         ;1F=deltaX hi
0907: d0 6b                        bne     HorizDom          ;if deltaX high is nonzero, we're primarily horizontal
0909: a5 1e                        lda     ]delta_xl         ;is this a vertical line?
090b: f0 0e                        beq     VerticalOrPoint   ;yup
090d: a5 ff                        lda     ]delta_y          ;is this a horizontal line?
090f: f0 2f                        beq     HorizontalLine    ;yup
0911: a5 1e                        lda     ]delta_xl         ;compare deltaX to deltaY
0913: 38                           sec
0914: e5 ff                        sbc     ]delta_y
0916: b0 5c                        bcs     HorizDom
0918: 4c ec 09                     jmp     VertDom

091b: a5 ff        VerticalOrPoint lda     ]delta_y          ;just a point?
091d: d0 06                        bne     VerticalLine      ;nope
091f: 20 60 08                     jsr     HandleDOT         ;yes, plot it
0922: 4c 3d 0a                     jmp     RestoreXY

0925: a5 fe        VerticalLine    lda     ARG_Y1            ;ensure Y1 > Y0
0927: 38                           sec
0928: e5 fb                        sbc     ARG_Y0
092a: b0 03                        bcs     :NoSwap
092c: 20 52 0a                     jsr     SwapCoords
092f: 20 60 08     :NoSwap         jsr     HandleDOT         ;draw a dot at X0,Y0
0932: e6 fb        :DrawLoop       inc     ARG_Y0            ;move down
0934: 20 60 08                     jsr     HandleDOT         ;draw a dot at X0,Y0
0937: a5 fb                        lda     ARG_Y0
0939: c5 fe                        cmp     ARG_Y1            ;done yet?
093b: d0 f5                        bne     :DrawLoop         ;no, keep going
093d: 4c 3d 0a                     jmp     RestoreXY

0940: 20 60 08     HorizontalLine  jsr     HandleDOT         ;draw a dot at X0,Y0
0943: e6 f9        HorizDrawLoop   inc     ARG_X0            ;move right
0945: d0 02                        bne     :NoInc
0947: e6 fa                        inc     ARG_X0+1
0949: 20 73 08     :NoInc          jsr     HandleDOT_1       ;draw a dot at X0,Y0, skipping Y addr setup
094c: a5 f9                        lda     ARG_X0            ;check if we're done
094e: c5 fc                        cmp     ARG_X1
0950: d0 f1                        bne     HorizDrawLoop
0952: a5 fa                        lda     ARG_X0+1
0954: c5 fd                        cmp     ARG_X1+1
0956: d0 eb                        bne     HorizDrawLoop
0958: 4c 3d 0a                     jmp     RestoreXY

                   ; Neither dominant - diagonal line.
095b: e6 f9        DiagonalDom     inc     ARG_X0            ;always move right
095d: d0 02                        bne     :NoInc
095f: e6 fa                        inc     ARG_X0+1
0961: a5 fb        :NoInc          lda     ARG_Y0            ;update Y coord
0963: 18                           clc
0964: 65 08                        adc     ]move_dir
0966: 85 fb                        sta     ARG_Y0
0968: 20 60 08                     jsr     HandleDOT         ;draw dot
096b: a5 fb                        lda     ARG_Y0
096d: c5 fe                        cmp     ARG_Y1            ;done yet?
096f: d0 ea                        bne     DiagonalDom       ;no, keep going
0971: 4c 3d 0a                     jmp     RestoreXY

                   ; Horizontally-dominant line.
0974: 20 60 08     HorizDom        jsr     HandleDOT         ;draw a point at X0,Y0
0977: a5 1e                        lda     ]delta_xl         ;check for purely-horizontal line
0979: 85 19                        sta     ]tmp_xl
097b: a5 1f                        lda     ]delta_xh
097d: 85 1a                        sta     ]tmp_xh
097f: a5 fe                        lda     ARG_Y1
0981: 38                           sec
0982: e5 fb                        sbc     ARG_Y0
0984: f0 bd                        beq     HorizDrawLoop     ;go be horizontal
0986: 90 06                        bcc     :Upward           ;line moves up
0988: a9 01                        lda     #$01              ;line moves downward
098a: 85 08                        sta     ]move_dir
098c: d0 04                        bne     L0992             ;(always)

098e: a9 ff        :Upward         lda     #$ff
0990: 85 08                        sta     ]move_dir
0992: a5 1f        L0992           lda     ]delta_xh         ;check for 1:1 diagonal
0994: d0 06                        bne     L099C
0996: a5 1e                        lda     ]delta_xl
0998: c5 ff                        cmp     ]delta_y
099a: f0 bf                        beq     DiagonalDom
099c: a5 1e        L099C           lda     ]delta_xl         ;set initial delta
099e: 38                           sec
099f: e5 ff                        sbc     ]delta_y
09a1: 85 1e                        sta     ]delta_xl
09a3: b0 02                        bcs     :HorizDomLoop
09a5: c6 1f                        dec     ]delta_xh
                   ; Core of horizontally-dominant line draw.
09a7: a5 1e        :HorizDomLoop   lda     ]delta_xl         ;do the delta adjustment to see if we need to move
09a9: 38                           sec                       ; vertically at this step
09aa: e5 ff                        sbc     ]delta_y
09ac: 85 1e                        sta     ]delta_xl
09ae: b0 04                        bcs     L09B4
09b0: c6 1f                        dec     ]delta_xh
09b2: 30 0c                        bmi     :MoveVert         ;yup, need to move vertically
09b4: e6 f9        L09B4           inc     ARG_X0            ;move right every time
09b6: d0 02                        bne     :NoInc
09b8: e6 fa                        inc     ARG_X0+1
09ba: 20 73 08     :NoInc          jsr     HandleDOT_1       ;draw dot without updating Y addr
09bd: 4c dd 09                     jmp     L09DD

09c0: a5 1e        :MoveVert       lda     ]delta_xl         ;update deltas
09c2: 18                           clc
09c3: 65 19                        adc     ]tmp_xl
09c5: 85 1e                        sta     ]delta_xl
09c7: a5 1f                        lda     ]delta_xh
09c9: 65 1a                        adc     ]tmp_xh
09cb: 85 1f                        sta     ]delta_xh
09cd: a5 fb                        lda     ARG_Y0            ;advance Y coordinate
09cf: 18                           clc
09d0: 65 08                        adc     ]move_dir
09d2: 85 fb                        sta     ARG_Y0
09d4: e6 f9                        inc     ARG_X0            ;move right every time
09d6: d0 02                        bne     :NoInc
09d8: e6 fa                        inc     ARG_X0+1
09da: 20 60 08     :NoInc          jsr     HandleDOT         ;draw dot after updating Y addr
09dd: a5 f9        L09DD           lda     ARG_X0            ;check if we're done
09df: c5 fc                        cmp     ARG_X1
09e1: d0 c4                        bne     :HorizDomLoop
09e3: a5 fa                        lda     ARG_X0+1
09e5: c5 fd                        cmp     ARG_X1+1
09e7: d0 be                        bne     :HorizDomLoop
09e9: 4c 3d 0a                     jmp     RestoreXY

                   ; Vertically-dominant line.
09ec: a5 fe        VertDom         lda     ARG_Y1            ;make sure Y1 > Y0
09ee: 38                           sec
09ef: e5 fb                        sbc     ARG_Y0
09f1: b0 0b                        bcs     :MoveRight
09f3: 20 52 0a                     jsr     SwapCoords
09f6: a9 ff                        lda     #$ff              ;move to the left
09f8: 85 08                        sta     ]move_dir
09fa: 85 09                        sta     ]move_dir_hi
09fc: 30 08                        bmi     :MoveSet

09fe: a9 01        :MoveRight      lda     #$01              ;move to the right
0a00: 85 08                        sta     ]move_dir
0a02: a9 00                        lda     #$00
0a04: 85 09                        sta     ]move_dir_hi
0a06: a5 ff        :MoveSet        lda     ]delta_y          ;configure deltas
0a08: 85 1b                        sta     ]count
0a0a: 85 19                        sta     ]tmp_xl
0a0c: 38                           sec
0a0d: e5 1e                        sbc     ]delta_xl
0a0f: 85 ff                        sta     ]delta_y
0a11: 20 60 08                     jsr     HandleDOT         ;draw dot at X0,Y0
0a14: a5 ff        :VertDomLoop    lda     ]delta_y          ;update delta, see if it's time to update X
0a16: 38                           sec
0a17: e5 1e                        sbc     ]delta_xl
0a19: 85 ff                        sta     ]delta_y
0a1b: b0 14                        bcs     :NoXMove
0a1d: a5 ff                        lda     ]delta_y
0a1f: 18                           clc
0a20: 65 19                        adc     ]tmp_xl
0a22: 85 ff                        sta     ]delta_y
0a24: a5 f9                        lda     ARG_X0            ;update X
0a26: 18                           clc
0a27: 65 08                        adc     ]move_dir
0a29: 85 f9                        sta     ARG_X0
0a2b: a5 fa                        lda     ARG_X0+1
0a2d: 65 09                        adc     ]move_dir_hi
0a2f: 85 fa                        sta     ARG_X0+1
0a31: e6 fb        :NoXMove        inc     ARG_Y0            ;Y always moves down
0a33: 20 60 08                     jsr     HandleDOT         ;draw dot at X0,Y0
0a36: c6 1b                        dec     ]count            ;done yet?
0a38: d0 da                        bne     :VertDomLoop      ;nope, keep going
0a3a: 4c 3d 0a                     jmp     RestoreXY

0a3d: ad 56 14     RestoreXY       lda     saved_xlo
0a40: 85 f9                        sta     ARG_X0
0a42: ad 57 14                     lda     saved_xhi
0a45: 85 fa                        sta     ARG_X0+1
0a47: ad 58 14                     lda     saved_y
0a4a: 85 fb                        sta     ARG_Y0
0a4c: ad 69 14                     lda     saved_1f
0a4f: 85 1f                        sta     ]delta_xh
0a51: 60                           rts

                   ; Swap X0,Y0 with X1,Y1 (F9/FA/FB <-> FC/FD/FE).
                   • Clear variables

0a52: a5 f9        SwapCoords      lda     ARG_X0
0a54: a6 fc                        ldx     ARG_X1
0a56: 86 f9                        stx     ARG_X0
0a58: 85 fc                        sta     ARG_X1
0a5a: a5 fa                        lda     ARG_X0+1
0a5c: a6 fd                        ldx     ARG_X1+1
0a5e: 86 fa                        stx     ARG_X0+1
0a60: 85 fd                        sta     ARG_X1+1
0a62: a5 fb                        lda     ARG_Y0
0a64: a4 fe                        ldy     ARG_Y1
0a66: 84 fb                        sty     ARG_Y0
0a68: 85 fe                        sta     ARG_Y1
0a6a: 60                           rts

                   ********************************************************************************
                   * Handle LINESET,colorIndex,x0,y0,dataPtr,index,dist,angle,drawMode            *
                   *                                                                              *
                   * Draws a series of lines from an array of vectors.                            *
                   *                                                                              *
                   * On entry:                                                                    *
                   *   $1F: colorIndex (0-3 for color, 4 for white)                               *
                   *   $F9/FA/FB: x0,y0                                                           *
                   *   $E8/E9: pointer to coord data (e.g. LBOLT @ 816/$330)                      *
                   *   $1E: index                                                                 *
                   *   $19: distance in tiles, x16 (will be 16-96)                                *
                   *   $1D: angle (0-255)                                                         *
                   *   $1C: drawMode                                                              *
                   *                                                                              *
                   * For LBOLT, the four entries correspond to the primary direction (0=left,     *
                   * 1=up, 2=right, 3=down).                                                      *
                   ********************************************************************************
                   • Clear variables
                   ]angle          .var    $1d    {addr/1}
                   ]entry_index    .var    $1e    {addr/1}   ;0-3
                   ]ptr            .var    $20    {addr/2}
                   ]data_index     .var    $22    {addr/1}
                   ]dist16         .var    $23    {addr/1}   ;distance, in tiles, x16

0a6b: a2 0a        HandleLINESET   ldx     #$0a              ;save $20-2a so we can use it
0a6d: b5 20        :SaveLoop       lda     ]ptr,x
0a6f: 9d 5b 14                     sta     scratch0,x
0a72: ca                           dex
0a73: 10 f8                        bpl     :SaveLoop
0a75: a5 19                        lda     ARG_DIST
0a77: 85 23                        sta     ]dist16
0a79: a5 e8                        lda     ARG_EXT_PTR
0a7b: 85 20                        sta     ]ptr
0a7d: a5 e9                        lda     ARG_EXT_PTR+1
0a7f: 85 21                        sta     ]ptr+1
0a81: a5 1e                        lda     ]entry_index      ;double index, use as file offset
0a83: 0a                           asl     A
0a84: a8                           tay
0a85: b1 20                        lda     (]ptr),y          ;offset lo
0a87: 85 19                        sta     ARG_DIST
0a89: c8                           iny
0a8a: b1 20                        lda     (]ptr),y          ;offset hi
0a8c: aa                           tax
0a8d: a5 19                        lda     ARG_DIST          ;update ptr
0a8f: 18                           clc
0a90: 65 20                        adc     ]ptr
0a92: 85 20                        sta     ]ptr
0a94: 8a                           txa
0a95: 65 21                        adc     ]ptr+1
0a97: 85 21                        sta     ]ptr+1
                   ; 
0a99: a9 00                        lda     #$00
0a9b: 85 22                        sta     ]data_index
0a9d: a4 22        PointLoop       ldy     ]data_index
0a9f: b1 20                        lda     (]ptr),y          ;get the X coord
0aa1: 85 fc                        sta     ARG_X1
0aa3: 20 2e 0b                     jsr     AdvancePtr        ;advance to next byte
0aa6: b1 20                        lda     (]ptr),y          ;get the Y coord
0aa8: 85 fe                        sta     ARG_Y1
0aaa: d0 0f                        bne     :NotZero
0aac: c5 fc                        cmp     ARG_X1            ;Y was zero, was X as well?
0aae: d0 0b                        bne     :NotZero
                   ; Found $00/$00, end of list reached.  Restore DP we trampled.
0ab0: a2 0a                        ldx     #$0a
0ab2: bd 5b 14     :RestoreLoop    lda     scratch0,x
0ab5: 95 20                        sta     ]ptr,x
0ab7: ca                           dex
0ab8: 10 f8                        bpl     :RestoreLoop
0aba: 60                           rts

0abb: 20 2e 0b     :NotZero        jsr     AdvancePtr        ;advance to next byte
0abe: 84 22                        sty     ]data_index       ;save this off
0ac0: a5 23                        lda     ]dist16           ;check the distance
0ac2: c9 10                        cmp     #16               ;1 tile?
0ac4: f0 03                        beq     :OneTile
0ac6: 20 34 0b                     jsr     ScaleVector
0ac9: a5 1d        :OneTile        lda     ]angle
0acb: f0 03                        beq     :NoAngle
0acd: 20 b5 0b                     jsr     RotateByAngle
0ad0: a9 00        :NoAngle        lda     #$00
0ad2: a6 fc                        ldx     ARG_X1            ;check X1 sign
0ad4: 10 02                        bpl     :XNeg
0ad6: a9 ff                        lda     #$ff
0ad8: 85 fd        :XNeg           sta     ARG_X1+1          ;sign-extend X1
0ada: a5 fc                        lda     ARG_X1            ;set X1 = X1 + X0
0adc: 18                           clc
0add: 65 f9                        adc     ARG_X0
0adf: 85 fc                        sta     ARG_X1
0ae1: a5 fd                        lda     ARG_X1+1
0ae3: 65 fa                        adc     ARG_X0+1
0ae5: 85 fd                        sta     ARG_X1+1
0ae7: a5 fe                        lda     ARG_Y1            ;set Y1 = Y1 + Y0
0ae9: 18                           clc
0aea: 65 fb                        adc     ARG_Y0
0aec: 85 fe                        sta     ARG_Y1
0aee: a4 22                        ldy     ]data_index
0af0: b1 20                        lda     (]ptr),y          ;get next byte
0af2: d0 03                        bne     :DoDraw           ;nonzero, draw a line
0af4: 4c 1a 0b                     jmp     :MoveOnly         ;zero, just move

0af7: 20 2e 0b     :DoDraw         jsr     AdvancePtr
0afa: 84 22                        sty     ]data_index
0afc: a5 1f                        lda     ARG_COLOR
0afe: c9 04                        cmp     #$04              ;green/purple/blue/orange?
0b00: 90 06                        bcc     :DrawColor        ;yes
0b02: 20 d0 08                     jsr     HandleLINE        ;no, white; draw solid line
0b05: 4c 9d 0a                     jmp     PointLoop

0b08: 46 fa        :DrawColor      lsr     ARG_X0+1          ;divide X coord by 2 for color mode
0b0a: 66 f9                        ror     ARG_X0
0b0c: 46 fd                        lsr     ARG_X1+1
0b0e: 66 fc                        ror     ARG_X1
0b10: 20 e7 11                     jsr     HandleCLINE       ;draw line
0b13: 06 f9                        asl     ARG_X0            ;restore X0
0b15: 26 fa                        rol     ARG_X0+1
0b17: 4c 9d 0a                     jmp     PointLoop

0b1a: 20 2e 0b     :MoveOnly       jsr     AdvancePtr        ;move to start of next entry
0b1d: 84 22                        sty     ]data_index
0b1f: a5 fc                        lda     ARG_X1            ;set X0=X1 (this is done by the line-drawing code)
0b21: 85 f9                        sta     ARG_X0
0b23: a5 fd                        lda     ARG_X1+1
0b25: 85 fa                        sta     ARG_X0+1
0b27: a5 fe                        lda     ARG_Y1
0b29: 85 fb                        sta     ARG_Y0
0b2b: 4c 9d 0a                     jmp     PointLoop

                   ; Increment 16-bit value in Y-reg and $21.
0b2e: c8           AdvancePtr      iny
0b2f: d0 02                        bne     :NoInc
0b31: e6 21                        inc     ]ptr+1
0b33: 60           :NoInc          rts

                   ; Scale the vector in X1/Y1 (part of LINESET).
                   ; 
                   ; On entry:
                   ;   Y-reg: dist * 16
                   ;   X1/Y1: vector to scale
                   ; 
                   ; On exit:
                   ;   Y-reg: (unchanged)
                   ;   X1/Y1 updated
0b34: a8           ScaleVector     tay                       ;put dist in Y-reg
0b35: a5 fc                        lda     ARG_X1
0b37: 20 44 0b                     jsr     ScaleVectorPart
0b3a: 85 fc                        sta     ARG_X1
0b3c: a5 fe                        lda     ARG_Y1
0b3e: 20 44 0b                     jsr     ScaleVectorPart
0b41: 85 fe                        sta     ARG_Y1
0b43: 60                           rts

                   ; Scale the delta value in A-reg by the value in Y-reg.
                   ; 
                   ; On exit:
                   ;   A-reg: scaled value
                   ;   Y-reg: unchanged
                   • Clear variables
                   ]saved_val      .var    $08    {addr/1}
                   ]tmpval         .var    $19    {addr/2}
                   ]xresult        .var    $1e    {addr/1}
                   ]mult_bit       .var    $25    {addr/1}
                   ]result_val     .var    $26    {addr/2}
                   ]xsign          .var    $28    {addr/1}
                   ]ysign          .var    $29    {addr/1}
                   ]ytemp          .var    $ff    {addr/1}

0b44: 85 08        ScaleVectorPart sta     ]saved_val
0b46: 85 1a                        sta     ]tmpval+1         ;put in high byte of 16-bit word
0b48: a9 00                        lda     #$00
0b4a: 85 19                        sta     ]tmpval
0b4c: 85 26                        sta     ]result_val
0b4e: 85 27                        sta     ]result_val+1
0b50: 46 1a                        lsr     ]tmpval+1         ;divide by 16
0b52: 66 19                        ror     ]tmpval
0b54: 46 1a                        lsr     ]tmpval+1
0b56: 66 19                        ror     ]tmpval
0b58: 46 1a                        lsr     ]tmpval+1
0b5a: 66 19                        ror     ]tmpval
0b5c: 46 1a                        lsr     ]tmpval+1
0b5e: 66 19                        ror     ]tmpval
0b60: a5 08                        lda     ]saved_val        ;is original negative?
0b62: 10 06                        bpl     :OrigPos
0b64: a5 1a                        lda     ]tmpval+1         ;yes, sign-extend
0b66: 09 f0                        ora     #$f0
0b68: 85 1a                        sta     ]tmpval+1
0b6a: a9 01        :OrigPos        lda     #$01              ;init multiplier
0b6c: 85 25                        sta     ]mult_bit
0b6e: 98           :MultLoop       tya
0b6f: 25 25                        and     ]mult_bit         ;add or shift?
0b71: f0 0d                        beq     :Shift
0b73: a5 19                        lda     ]tmpval           ;add to result
0b75: 18                           clc
0b76: 65 26                        adc     ]result_val
0b78: 85 26                        sta     ]result_val
0b7a: a5 1a                        lda     ]tmpval+1
0b7c: 65 27                        adc     ]result_val+1
0b7e: 85 27                        sta     ]result_val+1
0b80: 06 19        :Shift          asl     ]tmpval           ;multiply by 2
0b82: 26 1a                        rol     ]tmpval+1
0b84: 06 25                        asl     ]mult_bit
0b86: d0 e6                        bne     :MultLoop         ;repeat 8x
0b88: a5 08                        lda     ]saved_val
0b8a: 10 09                        bpl     :Pos
0b8c: a5 26                        lda     ]result_val
0b8e: 30 0b                        bmi     :Pos2
0b90: c6 27                        dec     ]result_val+1
0b92: 4c 9b 0b                     jmp     :Pos2

0b95: a5 26        :Pos            lda     ]result_val
0b97: 10 02                        bpl     :Pos2
0b99: e6 27                        inc     ]result_val+1
0b9b: a5 27        :Pos2           lda     ]result_val+1     ;result in high byte
0b9d: 60                           rts

0b9e: 85 08        DoScaleMult     sta     ]saved_val
0ba0: 85 19                        sta     ]tmpval
0ba2: a9 00                        lda     #$00
0ba4: 85 1a                        sta     ]tmpval+1
0ba6: 85 26                        sta     ]result_val
0ba8: 85 27                        sta     ]result_val+1
0baa: a5 08                        lda     ]saved_val        ;positive?
0bac: 10 bc                        bpl     :OrigPos
0bae: a9 ff                        lda     #$ff              ;no, sign-extend
0bb0: 85 1a                        sta     ]tmpval+1
0bb2: 4c 6a 0b                     jmp     :OrigPos

                   ; Rotates the coordinates by an arbitrary angle.  (Not used by CF.)
                   ; 
                   ; The angle value is 0-255.  64 rotates 90 degrees clockwise.
                   ; 
                   ; On entry:
                   ;   A-reg: angle (0-255)
                   ;   $FC: X coord (X1)
                   ;   $FE: Y coord (Y1)
0bb5: aa           RotateByAngle   tax                       ;save arg
0bb6: 4a                           lsr     A                 ;divide by 64 to get quadrant
0bb7: 4a                           lsr     A
0bb8: 4a                           lsr     A
0bb9: 4a                           lsr     A
0bba: 4a                           lsr     A
0bbb: 4a                           lsr     A                 ;now 0-3
0bbc: a8                           tay
0bbd: b9 6a 14                     lda     angle_xsign,y     ;get $01 or $ff depending on direction
0bc0: 85 28                        sta     ]xsign
0bc2: b9 6e 14                     lda     angle_ysign,y
0bc5: 85 29                        sta     ]ysign
                   ; XC = X * cos(theta) - Y * sin(theta)
0bc7: 8a                           txa                       ;get arg
0bc8: 29 7f                        and     #$7f              ;strip the hi bit
0bca: aa                           tax
0bcb: bd 36 17                     lda     angle_cos,x
0bce: a8                           tay
0bcf: a5 fc                        lda     ARG_X1
0bd1: 20 9e 0b                     jsr     DoScaleMult
0bd4: a4 29                        ldy     ]ysign            ;should it be positive?
0bd6: 10 05                        bpl     :XCosPos          ;yes
0bd8: 49 ff                        eor     #$ff              ;make negative (invert and add one)
0bda: 18                           clc
0bdb: 69 01                        adc     #$01
0bdd: 85 1e        :XCosPos        sta     ]xresult
0bdf: 8a                           txa
0be0: bd b6 16                     lda     angle_sin,x
0be3: a8                           tay
0be4: a5 fe                        lda     ARG_Y1
0be6: 20 9e 0b                     jsr     DoScaleMult
0be9: a4 28                        ldy     ]xsign            ;should it be positive?
0beb: 30 05                        bmi     :YSinNeg          ;no
0bed: 49 ff                        eor     #$ff              ;yes, but we're subtracting, so invert it
0bef: 18                           clc
0bf0: 69 01                        adc     #$01
0bf2: 18           :YSinNeg        clc
0bf3: 65 1e                        adc     ]xresult
0bf5: 85 1e                        sta     ]xresult
                   ; YC = Y * cos(theta) + X * sin(theta)
0bf7: 8a                           txa
0bf8: bd b6 16                     lda     angle_sin,x
0bfb: a8                           tay
0bfc: a5 fc                        lda     ARG_X1
0bfe: 20 9e 0b                     jsr     DoScaleMult
0c01: a4 28                        ldy     ]xsign            ;check sign
0c03: 10 05                        bpl     :XSinPos
0c05: 49 ff                        eor     #$ff              ;should be negative, invert
0c07: 18                           clc
0c08: 69 01                        adc     #$01
0c0a: 85 ff        :XSinPos        sta     ]ytemp
0c0c: 8a                           txa
0c0d: bd 36 17                     lda     angle_cos,x
0c10: a8                           tay
0c11: a5 fe                        lda     ARG_Y1
0c13: 20 9e 0b                     jsr     DoScaleMult
0c16: a4 29                        ldy     ]ysign            ;check sign
0c18: 10 05                        bpl     :YCosPos
0c1a: 49 ff                        eor     #$ff              ;should be negative, invert
0c1c: 18                           clc
0c1d: 69 01                        adc     #$01
0c1f: 18           :YCosPos        clc
0c20: 65 ff                        adc     ]ytemp
0c22: 85 fe                        sta     ARG_Y1
0c24: a5 1e                        lda     ]xresult
0c26: 85 fc                        sta     ARG_X1
0c28: 60                           rts

                   ********************************************************************************
                   * Handle CLR,color                                                             *
                   *                                                                              *
                   * On entry:                                                                    *
                   *   $FF - color index (0-7)                                                    *
                   *                                                                              *
                   * The color index matches the Applesoft colors (black0, green, purple, ...).   *
                   ********************************************************************************
0c29: a0 5d        HandleCLR       ldy     #93               ;(32 - 1) * 3
                   ; OR the page into the 32 STA statements
0c2b: ae 85 14                     ldx     hpage
0c2e: 8a           :SetLoop        txa
0c2f: 19 43 0c                     ora     :_ClearLoop+2,y
0c32: 99 43 0c                     sta     :_ClearLoop+2,y
0c35: 88                           dey
0c36: 88                           dey
0c37: 88                           dey
0c38: 10 f4                        bpl     :SetLoop
                   ; do the clear
0c3a: a0 00                        ldy     #$00
0c3c: a6 ff                        ldx     ]ytemp
0c3e: bd 72 14                     lda     clr_color_table,x
0c41: 99 00 00     :_ClearLoop     sta     HIRES_PAGE_1-$2000,y ;unroll loop for speed
0c44: 99 00 01                     sta     HIRES_PAGE_1-$1f00,y
0c47: 99 00 02                     sta     HIRES_PAGE_1-$1e00,y
0c4a: 99 00 03                     sta     HIRES_PAGE_1-$1d00,y
0c4d: 99 00 04                     sta     HIRES_PAGE_1-$1c00,y
0c50: 99 00 05                     sta     HIRES_PAGE_1-$1b00,y
0c53: 99 00 06                     sta     HIRES_PAGE_1-$1a00,y
0c56: 99 00 07                     sta     HIRES_PAGE_1-$1900,y
0c59: 99 00 08                     sta     HIRES_PAGE_1-$1800,y
0c5c: 99 00 09                     sta     HIRES_PAGE_1-$1700,y
0c5f: 99 00 0a                     sta     HIRES_PAGE_1-$1600,y
0c62: 99 00 0b                     sta     HIRES_PAGE_1-$1500,y
0c65: 99 00 0c                     sta     HIRES_PAGE_1-$1400,y
0c68: 99 00 0d                     sta     HIRES_PAGE_1-$1300,y
0c6b: 99 00 0e                     sta     HIRES_PAGE_1-$1200,y
0c6e: 99 00 0f                     sta     HIRES_PAGE_1-$1100,y
0c71: 99 00 10                     sta     HIRES_PAGE_1-$1000,y
0c74: 99 00 11                     sta     HIRES_PAGE_1-$f00,y
0c77: 99 00 12                     sta     HIRES_PAGE_1-$e00,y
0c7a: 99 00 13                     sta     HIRES_PAGE_1-$d00,y
0c7d: 99 00 14                     sta     HIRES_PAGE_1-$c00,y
0c80: 99 00 15                     sta     HIRES_PAGE_1-$b00,y
0c83: 99 00 16                     sta     HIRES_PAGE_1-$a00,y
0c86: 99 00 17                     sta     HIRES_PAGE_1-$900,y
0c89: 99 00 18                     sta     HIRES_PAGE_1-$800,y
0c8c: 99 00 19                     sta     HIRES_PAGE_1-$700,y
0c8f: 99 00 1a                     sta     HIRES_PAGE_1-$600,y
0c92: 99 00 1b                     sta     HIRES_PAGE_1-$500,y
0c95: 99 00 1c                     sta     HIRES_PAGE_1-$400,y
0c98: 99 00 1d                     sta     HIRES_PAGE_1-$300,y
0c9b: 99 00 1e                     sta     HIRES_PAGE_1-$200,y
0c9e: 99 00 1f                     sta     HIRES_PAGE_1-$100,y
0ca1: 8a                           txa
0ca2: 49 08                        eor     #$08              ;flip odd/even color index
0ca4: aa                           tax
0ca5: bd 72 14                     lda     clr_color_table,x ;get color
0ca8: c8                           iny
0ca9: d0 96                        bne     :_ClearLoop       ;loop until done
                   ; reset the STA statements
0cab: a0 5d                        ldy     #$5d
0cad: ad 85 14                     lda     hpage
0cb0: 49 ff                        eor     #$ff
0cb2: aa                           tax
0cb3: 8a           :ResetLoop      txa
0cb4: 39 43 0c                     and     :_ClearLoop+2,y
0cb7: 99 43 0c                     sta     :_ClearLoop+2,y
0cba: 88                           dey
0cbb: 88                           dey
0cbc: 88                           dey
0cbd: 10 f4                        bpl     :ResetLoop
0cbf: 60                           rts

                   ********************************************************************************
                   * Handle SCFLIP,mode                                                           *
                   *                                                                              *
                   * Changes the colors on the hi-res screen by exclusive-ORing every byte with a *
                   * mask.                                                                        *
                   *                                                                              *
                   * On entry:                                                                    *
                   *   $FF: mask (0=$7F, 1=$80, 2=$FF)                                            *
                   ********************************************************************************
                   • Clear variables

0cc0: a0 e0        HandleSCFLIP    ldy     #224              ;32 pairs * 7 bytes each
0cc2: ae 85 14                     ldx     hpage
0cc5: 8a           :SetLoop        txa
0cc6: 19 e0 0c                     ora     :_FlipInst1,y     ;not actually modifying target instruction; last mod
0cc9: 99 e0 0c                     sta     :_FlipInst1,y     ; is _FlipInst1+7
0ccc: 8a                           txa
0ccd: 19 e3 0c                     ora     :_FlipInst2,y
0cd0: 99 e3 0c                     sta     :_FlipInst2,y
0cd3: 88                           dey
0cd4: 88                           dey
0cd5: 88                           dey
0cd6: 88                           dey
0cd7: 88                           dey
0cd8: 88                           dey
0cd9: 88                           dey
0cda: d0 e9                        bne     :SetLoop
0cdc: a0 00                        ldy     #$00
0cde: a6 ff                        ldx     ARG_FF
0ce0: bd 82 14     :_FlipInst1     lda     flip_pattern,x
0ce3: aa           :_FlipInst2     tax
0ce4: 8a           :FlipLoop       txa
0ce5: 59 00 00                     eor     HIRES_PAGE_1-$2000,y ;unroll loop for speed
0ce8: 99 00 00                     sta     HIRES_PAGE_1-$2000,y
0ceb: 8a                           txa
0cec: 59 00 01                     eor     HIRES_PAGE_1-$1f00,y
0cef: 99 00 01                     sta     HIRES_PAGE_1-$1f00,y
0cf2: 8a                           txa
0cf3: 59 00 02                     eor     HIRES_PAGE_1-$1e00,y
0cf6: 99 00 02                     sta     HIRES_PAGE_1-$1e00,y
0cf9: 8a                           txa
0cfa: 59 00 03                     eor     HIRES_PAGE_1-$1d00,y
0cfd: 99 00 03                     sta     HIRES_PAGE_1-$1d00,y
0d00: 8a                           txa
0d01: 59 00 04                     eor     HIRES_PAGE_1-$1c00,y
0d04: 99 00 04                     sta     HIRES_PAGE_1-$1c00,y
0d07: 8a                           txa
0d08: 59 00 05                     eor     HIRES_PAGE_1-$1b00,y
0d0b: 99 00 05                     sta     HIRES_PAGE_1-$1b00,y
0d0e: 8a                           txa
0d0f: 59 00 06                     eor     HIRES_PAGE_1-$1a00,y
0d12: 99 00 06                     sta     HIRES_PAGE_1-$1a00,y
0d15: 8a                           txa
0d16: 59 00 07                     eor     HIRES_PAGE_1-$1900,y
0d19: 99 00 07                     sta     HIRES_PAGE_1-$1900,y
0d1c: 8a                           txa
0d1d: 59 00 08                     eor     HIRES_PAGE_1-$1800,y
0d20: 99 00 08                     sta     HIRES_PAGE_1-$1800,y
0d23: 8a                           txa
0d24: 59 00 09                     eor     HIRES_PAGE_1-$1700,y
0d27: 99 00 09                     sta     HIRES_PAGE_1-$1700,y
0d2a: 8a                           txa
0d2b: 59 00 0a                     eor     HIRES_PAGE_1-$1600,y
0d2e: 99 00 0a                     sta     HIRES_PAGE_1-$1600,y
0d31: 8a                           txa
0d32: 59 00 0b                     eor     HIRES_PAGE_1-$1500,y
0d35: 99 00 0b                     sta     HIRES_PAGE_1-$1500,y
0d38: 8a                           txa
0d39: 59 00 0c                     eor     HIRES_PAGE_1-$1400,y
0d3c: 99 00 0c                     sta     HIRES_PAGE_1-$1400,y
0d3f: 8a                           txa
0d40: 59 00 0d                     eor     HIRES_PAGE_1-$1300,y
0d43: 99 00 0d                     sta     HIRES_PAGE_1-$1300,y
0d46: 8a                           txa
0d47: 59 00 0e                     eor     HIRES_PAGE_1-$1200,y
0d4a: 99 00 0e                     sta     HIRES_PAGE_1-$1200,y
0d4d: 8a                           txa
0d4e: 59 00 0f                     eor     HIRES_PAGE_1-$1100,y
0d51: 99 00 0f                     sta     HIRES_PAGE_1-$1100,y
0d54: 8a                           txa
0d55: 59 00 10                     eor     HIRES_PAGE_1-$1000,y
0d58: 99 00 10                     sta     HIRES_PAGE_1-$1000,y
0d5b: 8a                           txa
0d5c: 59 00 11                     eor     HIRES_PAGE_1-$f00,y
0d5f: 99 00 11                     sta     HIRES_PAGE_1-$f00,y
0d62: 8a                           txa
0d63: 59 00 12                     eor     HIRES_PAGE_1-$e00,y
0d66: 99 00 12                     sta     HIRES_PAGE_1-$e00,y
0d69: 8a                           txa
0d6a: 59 00 13                     eor     HIRES_PAGE_1-$d00,y
0d6d: 99 00 13                     sta     HIRES_PAGE_1-$d00,y
0d70: 8a                           txa
0d71: 59 00 14                     eor     HIRES_PAGE_1-$c00,y
0d74: 99 00 14                     sta     HIRES_PAGE_1-$c00,y
0d77: 8a                           txa
0d78: 59 00 15                     eor     HIRES_PAGE_1-$b00,y
0d7b: 99 00 15                     sta     HIRES_PAGE_1-$b00,y
0d7e: 8a                           txa
0d7f: 59 00 16                     eor     HIRES_PAGE_1-$a00,y
0d82: 99 00 16                     sta     HIRES_PAGE_1-$a00,y
0d85: 8a                           txa
0d86: 59 00 17                     eor     HIRES_PAGE_1-$900,y
0d89: 99 00 17                     sta     HIRES_PAGE_1-$900,y
0d8c: 8a                           txa
0d8d: 59 00 18                     eor     HIRES_PAGE_1-$800,y
0d90: 99 00 18                     sta     HIRES_PAGE_1-$800,y
0d93: 8a                           txa
0d94: 59 00 19                     eor     HIRES_PAGE_1-$700,y
0d97: 99 00 19                     sta     HIRES_PAGE_1-$700,y
0d9a: 8a                           txa
0d9b: 59 00 1a                     eor     HIRES_PAGE_1-$600,y
0d9e: 99 00 1a                     sta     HIRES_PAGE_1-$600,y
0da1: 8a                           txa
0da2: 59 00 1b                     eor     HIRES_PAGE_1-$500,y
0da5: 99 00 1b                     sta     HIRES_PAGE_1-$500,y
0da8: 8a                           txa
0da9: 59 00 1c                     eor     HIRES_PAGE_1-$400,y
0dac: 99 00 1c                     sta     HIRES_PAGE_1-$400,y
0daf: 8a                           txa
0db0: 59 00 1d                     eor     HIRES_PAGE_1-$300,y
0db3: 99 00 1d                     sta     HIRES_PAGE_1-$300,y
0db6: 8a                           txa
0db7: 59 00 1e                     eor     HIRES_PAGE_1-$200,y
0dba: 99 00 1e                     sta     HIRES_PAGE_1-$200,y
0dbd: 8a                           txa
0dbe: 59 00 1f                     eor     HIRES_PAGE_1-$100,y
0dc1: 99 00 1f                     sta     HIRES_PAGE_1-$100,y
0dc4: c8                           iny
0dc5: f0 03                        beq     :Done
0dc7: 4c e4 0c                     jmp     :FlipLoop

0dca: a0 e0        :Done           ldy     #224              ;now strip the hpage out of the instructions
0dcc: ad 85 14                     lda     hpage             ; so it's clean for next time
0dcf: 49 ff                        eor     #$ff
0dd1: aa                           tax
0dd2: 8a           :ResetLoop      txa
0dd3: 39 e0 0c                     and     :_FlipInst1,y
0dd6: 99 e0 0c                     sta     :_FlipInst1,y
0dd9: 8a                           txa
0dda: 39 e3 0c                     and     :_FlipInst2,y
0ddd: 99 e3 0c                     sta     :_FlipInst2,y
0de0: 88                           dey
0de1: 88                           dey
0de2: 88                           dey
0de3: 88                           dey
0de4: 88                           dey
0de5: 88                           dey
0de6: 88                           dey
0de7: d0 e9                        bne     :ResetLoop
0de9: 60                           rts

                   ********************************************************************************
                   * Handle HISCROLL                                                              *
                   *                                                                              *
                   * Scrolls the hi-res screen up one line.                                       *
                   ********************************************************************************
                   • Clear variables
                   ]dst_ptr        .var    $06    {addr/2}
                   ]src_ptr        .var    $08    {addr/2}

0dea: a2 00        HandleHISCROLL  ldx     #$00              ;destination is row 0
0dec: bd b6 17     :RowLoop        lda     hr_addr_lo,x
0def: 85 06                        sta     ]dst_ptr
0df1: bd 76 18                     lda     hr_addr_hi,x
0df4: 0d 85 14                     ora     hpage
0df7: 85 07                        sta     ]dst_ptr+1
0df9: e8                           inx                       ;source is row 1
0dfa: bd b6 17                     lda     hr_addr_lo,x
0dfd: 85 08                        sta     ]src_ptr
0dff: bd 76 18                     lda     hr_addr_hi,x
0e02: 85 09                        sta     ]src_ptr+1
0e04: a0 27                        ldy     #39               ;40 bytes per line
0e06: b1 08        :ColLoop        lda     (]src_ptr),y
0e08: 91 06                        sta     (]dst_ptr),y
0e0a: 88                           dey
0e0b: 10 f9                        bpl     :ColLoop
0e0d: e0 bf                        cpx     #191              ;191 rows
0e0f: d0 db                        bne     :RowLoop
                   ; clear bottom line
0e11: a0 27                        ldy     #39
0e13: a9 00                        lda     #$00
0e15: 99 d0 3f     :ClearLoop      sta     HIRES_PAGE_1+$1fd0,y
0e18: 88                           dey
0e19: 10 fa                        bpl     :ClearLoop
0e1b: 60                           rts

                   ********************************************************************************
                   * Handle BOX,X0,Y0,X1,Y1,drawMode,isFilled                                     *
                   *                                                                              *
                   * Draws a rectangle.                                                           *
                   *                                                                              *
                   * On entry:                                                                    *
                   *   $F9/FA/FB: x0,y0 (top left)                                                *
                   *   $FC/FD/FE: x1,y1 (bottom right)                                            *
                   *   $1C: drawMode (0=draw, 1=erase, 2=invert)                                  *
                   *   $FF: fill flag (0=outline, nonzero=filled)                                 *
                   ********************************************************************************
0e1c: a5 ff        HandleBOX       lda     ARG_FF            ;filled rect?
0e1e: d0 66                        bne     FillBox           ;yes, branch
0e20: a5 f9                        lda     ARG_X0
0e22: 8d 5b 14                     sta     scratch0
0e25: a5 fa                        lda     ARG_X0+1
0e27: 8d 5c 14                     sta     scratch1
0e2a: a5 fe                        lda     ARG_Y1
0e2c: 8d 5e 14                     sta     scratch3
0e2f: a5 fb                        lda     ARG_Y0
0e31: 8d 5d 14                     sta     scratch2
0e34: 85 fe                        sta     ARG_Y1
0e36: a5 fc                        lda     ARG_X1
0e38: 8d 5f 14                     sta     scratch4
0e3b: a5 fd                        lda     ARG_X1+1
0e3d: 8d 60 14                     sta     scratch5
0e40: 20 d0 08                     jsr     HandleLINE        ;draw X0,Y0 to X1,Y0
0e43: 20 60 08                     jsr     HandleDOT         ;plot X1,Y0
0e46: ad 5f 14                     lda     scratch4
0e49: 85 fc                        sta     ARG_X1
0e4b: ad 60 14                     lda     scratch5
0e4e: 85 fd                        sta     ARG_X1+1
0e50: ad 5e 14                     lda     scratch3
0e53: 85 fe                        sta     ARG_Y1
0e55: 20 d0 08                     jsr     HandleLINE        ;plot X1,Y0 to X1,Y1
0e58: 20 60 08                     jsr     HandleDOT         ;plot X1,Y1
0e5b: ad 5e 14                     lda     scratch3
0e5e: 85 fe                        sta     ARG_Y1
0e60: ad 5b 14                     lda     scratch0
0e63: 85 fc                        sta     ARG_X1
0e65: ad 5c 14                     lda     scratch1
0e68: 85 fd                        sta     ARG_X1+1
0e6a: 20 d0 08                     jsr     HandleLINE        ;plot X1,Y1 to X0,Y1
0e6d: 20 60 08                     jsr     HandleDOT         ;plot X0,Y1
0e70: ad 5b 14                     lda     scratch0
0e73: 85 fc                        sta     ARG_X1
0e75: ad 5c 14                     lda     scratch1
0e78: 85 fd                        sta     ARG_X1+1
0e7a: ad 5d 14                     lda     scratch2
0e7d: 85 fe                        sta     ARG_Y1
0e7f: 20 d0 08                     jsr     HandleLINE        ;plot X0,y1 to X0,Y0
0e82: 20 60 08                     jsr     HandleDOT         ;plot X0,Y0
0e85: 60                           rts

0e86: a2 01        FillBox         ldx     #$01              ;configure Y direction
0e88: a5 fe                        lda     ARG_Y1            ;Y1 > Y0?
0e8a: 38                           sec
0e8b: e5 fb                        sbc     ARG_Y0
0e8d: b0 02                        bcs     L0E91             ;yes, count up
0e8f: a2 ff                        ldx     #$ff              ;no, count down
0e91: 8e 5d 14     L0E91           stx     scratch2
0e94: a5 fe                        lda     ARG_Y1            ;save X0/Y0/Y1
0e96: 8d 5e 14                     sta     scratch3
0e99: a5 f9                        lda     ARG_X0
0e9b: 8d 5b 14                     sta     scratch0
0e9e: a5 fa                        lda     ARG_X0+1
0ea0: 8d 5c 14                     sta     scratch1
0ea3: a5 fb                        lda     ARG_Y0            ;copy Y0 to Y1
0ea5: 85 fe                        sta     ARG_Y1
0ea7: a5 fc                        lda     ARG_X1            ;save X1
0ea9: 8d 5f 14                     sta     scratch4
0eac: a5 fd                        lda     ARG_X1+1
0eae: 8d 60 14                     sta     scratch5
0eb1: 20 d0 08     :FillBoxLoop    jsr     HandleLINE        ;draw X0,Y0 to X1,Y1
0eb4: ad 5b 14                     lda     scratch0          ;restore X0/X1
0eb7: 85 f9                        sta     ARG_X0
0eb9: ad 5c 14                     lda     scratch1
0ebc: 85 fa                        sta     ARG_X0+1
0ebe: ad 5f 14                     lda     scratch4
0ec1: 85 fc                        sta     ARG_X1
0ec3: ad 60 14                     lda     scratch5
0ec6: 85 fd                        sta     ARG_X1+1
0ec8: a5 fb                        lda     ARG_Y0            ;get Y0
0eca: cd 5e 14                     cmp     scratch3          ;are we done yet?
0ecd: f0 0b                        beq     :Done
0ecf: 18                           clc                       ;update Y
0ed0: 6d 5d 14                     adc     scratch2
0ed3: 85 fb                        sta     ARG_Y0            ;stick into Y0/Y1
0ed5: 85 fe                        sta     ARG_Y1
0ed7: 4c b1 0e                     jmp     :FillBoxLoop

0eda: 60           :Done           rts

                   ********************************************************************************
                   * Handle SWITCHC                                                               *
                   *                                                                              *
                   * Flips the high bits on the bit patterns we use to draw points.  Affects any  *
                   * routine that uses DOT to perform rendering.                                  *
                   ********************************************************************************
0edb: a2 00        HandleSWITCHC   ldx     #$00
0edd: bd 4e 1a     :Loop           lda     mod7_lo,x         ;do 0-139 and 140-279 in parallel
0ee0: 49 80                        eor     #$80
0ee2: 9d 4e 1a                     sta     mod7_lo,x
0ee5: bd da 1a                     lda     mod7_lo+140,x
0ee8: 49 80                        eor     #$80
0eea: 9d da 1a                     sta     mod7_lo+140,x
0eed: e8                           inx
0eee: e0 8c                        cpx     #140
0ef0: d0 eb                        bne     :Loop
0ef2: 60                           rts

                   ********************************************************************************
                   * Handle CHARSET,X0,Y0,itemIndex,dataPtr,drawMode                              *
                   *                                                                              *
                   * Draws a graphic from a compressed bitmap.                                    *
                   *                                                                              *
                   * On entry:                                                                    *
                   *   $F9/FA/FB: x0,y0 (top left)                                                *
                   *   $1E: item index                                                            *
                   *   $E8/E9: pointer to image data set                                          *
                   *   $1C: drawMode (0=draw, 1=erase, 2=invert)                                  *
                   *                                                                              *
                   * The image data set looks like this:                                          *
                   *  +00 max index (count + 1)                                                   *
                   *  +01 image0 params (4 bytes)                                                 *
                   *  +05 image1 params (4 bytes)                                                 *
                   *  ...                                                                         *
                   *  +xx image0 data                                                             *
                   *                                                                              *
                   * The image parameter blocks look like:                                        *
                   *   +00/01 offset to data from start of set                                    *
                   *   +02 width, in pixels                                                       *
                   *   +03 height, in pixels                                                      *
                   *                                                                              *
                   * The image data itself is 8-bit bytes, with one bit per pixel.  If a bit is   *
                   * set, the pixel should be drawn; otherwise, the existing pixel value should   *
                   * be left alone.  This is a compact representation of a monochrome bitmap with *
                   * transparency.                                                                *
                   ********************************************************************************
                   • Clear variables
                   ]hptr           .var    $06    {addr/2}
                   ]src_ptr        .var    $08    {addr/2}
                   ]data_offset    .var    $19    {addr/2}
                   ]item_index     .var    $1e    {addr/1}
                   ]num_cols       .var    $fc    {addr/1}
                   ]num_rows       .var    $fd    {addr/1}
                   ]col_count      .var    $fe    {addr/1}
                   ]row_count      .var    $ff    {addr/1}

0ef3: a6 1e        HandleCHARSET   ldx     ]item_index       ;get index
0ef5: a0 00                        ldy     #$00
0ef7: b1 e8                        lda     (ARG_EXT_PTR),y   ;check vs. max
0ef9: c5 1e                        cmp     ]item_index
0efb: b0 0a                        bcs     :InRange          ;max is >= index, good
0efd: 20 dd fb                     jsr     MON_BELL1         ;failed
0f00: 20 dd fb                     jsr     MON_BELL1
0f03: 20 dd fb                     jsr     MON_BELL1
0f06: 60                           rts

0f07: 98           :InRange        tya                       ;set A=0
0f08: 86 08                        stx     ]src_ptr          ;compute offset = index * 4
0f0a: 85 09                        sta     ]src_ptr+1
0f0c: 06 08                        asl     ]src_ptr
0f0e: 26 09                        rol     ]src_ptr+1
0f10: 06 08                        asl     ]src_ptr
0f12: 26 09                        rol     ]src_ptr+1
0f14: a5 08                        lda     ]src_ptr          ;add offset to external data ptr
0f16: 38                           sec                       ;set carry to add +1
0f17: 65 e8                        adc     ARG_EXT_PTR
0f19: 85 08                        sta     ]src_ptr
0f1b: a5 09                        lda     ]src_ptr+1
0f1d: 65 e9                        adc     ARG_EXT_PTR+1
0f1f: 85 09                        sta     ]src_ptr+1
                   ; Pull shape offset, width, and height out of external data buffer.
0f21: a0 00                        ldy     #$00
0f23: b1 08                        lda     (]src_ptr),y
0f25: 85 19                        sta     ]data_offset
0f27: c8                           iny
0f28: b1 08                        lda     (]src_ptr),y
0f2a: 85 1a                        sta     ]data_offset+1
0f2c: c8                           iny
0f2d: b1 08                        lda     (]src_ptr),y
0f2f: 85 fc                        sta     ]num_cols
0f31: c8                           iny
0f32: b1 08                        lda     (]src_ptr),y
0f34: 85 fd                        sta     ]num_rows
0f36: a5 19                        lda     ]data_offset
0f38: 18                           clc
0f39: 65 e8                        adc     ARG_EXT_PTR
0f3b: 85 08                        sta     ]src_ptr          ;set src pointer
0f3d: a5 1a                        lda     ]data_offset+1
0f3f: 65 e9                        adc     ARG_EXT_PTR+1
0f41: 85 09                        sta     ]src_ptr+1
                   ]bit_mask       .var    $1d    {addr/1}
                   ]saved_x0       .var    $f9    {addr/2}

0f43: a5 fd        FromPenguin     lda     ]num_rows
0f45: 85 ff                        sta     ]row_count
0f47: a9 01                        lda     #$01              ;bit to extract
0f49: 85 1d                        sta     ]bit_mask
0f4b: a5 f9                        lda     ]saved_x0
0f4d: 85 19                        sta     ]data_offset
0f4f: a5 fa                        lda     ]saved_x0+1
0f51: 85 1a                        sta     ]data_offset+1
0f53: a5 fc        :LineLoop       lda     ]num_cols
0f55: 85 fe                        sta     ]col_count
                   ; set up hi-res ptr
0f57: a4 fb                        ldy     ARG_Y0
0f59: b9 b6 17                     lda     hr_addr_lo,y
0f5c: 85 06                        sta     ]hptr
0f5e: b9 76 18                     lda     hr_addr_hi,y
0f61: 0d 85 14                     ora     hpage
0f64: 85 07                        sta     ]hptr+1
                   ; plot points based on bits in data
0f66: a0 00        :DrawLoop       ldy     #$00              ;get byte of data
0f68: b1 08                        lda     (]src_ptr),y
0f6a: 25 1d                        and     ]bit_mask         ;is the bit set?
0f6c: f0 03                        beq     :NoDraw           ;nope, don't draw here
0f6e: 20 73 08                     jsr     HandleDOT_1       ;draw at X0
0f71: 06 1d        :NoDraw         asl     ]bit_mask         ;move to the next bit
0f73: 90 08                        bcc     :NoInc            ;if we haven't done all 8 bits yet, continue
0f75: e6 1d                        inc     ]bit_mask         ;set bit_mask = 1
0f77: e6 08                        inc     ]src_ptr          ;move to the next byte
0f79: d0 02                        bne     :NoInc            ;(note we only do this at 8 bits; there are no
0f7b: e6 09                        inc     ]src_ptr+1        ; padding bits for non-multiple of 8 rows)
0f7d: e6 f9        :NoInc          inc     ]saved_x0         ;advance X coordinate
0f7f: d0 02                        bne     :NoIncX
0f81: e6 fa                        inc     ]saved_x0+1
0f83: c6 fe        :NoIncX         dec     ]col_count        ;count down number of pixels in this row
0f85: d0 df                        bne     :DrawLoop         ;not done yet
0f87: e6 fb                        inc     ARG_Y0            ;row done, move to the next
0f89: a5 19                        lda     ]data_offset      ;restore X0
0f8b: 85 f9                        sta     ]saved_x0
0f8d: a5 1a                        lda     ]data_offset+1
0f8f: 85 fa                        sta     ]saved_x0+1
0f91: c6 ff                        dec     ]row_count        ;done with all rows?
0f93: d0 be                        bne     :LineLoop         ;not yet
0f95: 60                           rts

                   ********************************************************************************
                   * Handle BDRW,X0,Y0,shapeIndex,dataPtr                                         *
                   *                                                                              *
                   * Draws a bitmap on the hi-res screen.                                         *
                   *                                                                              *
                   * On entry:                                                                    *
                   *   $F9/FA/FB: x0,y0                                                           *
                   *   $1E: shape index                                                           *
                   *   $E8/E9: shape data ptr                                                     *
                   ********************************************************************************
                   • Clear variables
                   ]hptr           .var    $06    {addr/2}
                   ]col_ctr        .var    $08    {addr/1}
                   ]src_ptr        .var    $19    {addr/2}
                   ]row_ctr        .var    $1b    {addr/1}
                   ]shape_index    .var    $1e    {addr/1}

0f96: a5 e8        HandleBDRW      lda     ARG_EXT_PTR
0f98: 85 19                        sta     ]src_ptr
0f9a: a5 e9                        lda     ARG_EXT_PTR+1
0f9c: 85 1a                        sta     ]src_ptr+1
0f9e: a6 1e                        ldx     ]shape_index      ;get the index, and multiply by 84
0fa0: ca           :Mult84         dex                       ; to get the shape offset
0fa1: 30 10                        bmi     :GotPtr
0fa3: a5 19                        lda     ]src_ptr
0fa5: 18                           clc
0fa6: 69 54                        adc     #84               ;4 * 21
0fa8: 85 19                        sta     ]src_ptr
0faa: a5 1a                        lda     ]src_ptr+1
0fac: 69 00                        adc     #$00
0fae: 85 1a                        sta     ]src_ptr+1
0fb0: 4c a0 0f                     jmp     :Mult84

0fb3: a9 00        :GotPtr         lda     #$00
0fb5: 85 1b        :RowLoop        sta     ]row_ctr
0fb7: a5 fb                        lda     ARG_Y0            ;set up hi-res address
0fb9: 18                           clc
0fba: 65 1b                        adc     ]row_ctr
0fbc: a8                           tay
0fbd: b9 b6 17                     lda     hr_addr_lo,y
0fc0: 85 06                        sta     ]hptr
0fc2: b9 76 18                     lda     hr_addr_hi,y
0fc5: 0d 85 14                     ora     hpage
0fc8: 85 07                        sta     ]hptr+1
0fca: a9 00                        lda     #$00              ;start from left column
0fcc: 85 08                        sta     ]col_ctr
0fce: a0 00        :ColLoop        ldy     #$00
0fd0: b1 19                        lda     (]src_ptr),y
0fd2: aa                           tax
0fd3: e6 19                        inc     ]src_ptr
0fd5: d0 02                        bne     :NoInc
0fd7: e6 1a                        inc     ]src_ptr+1
0fd9: a5 f9        :NoInc          lda     ARG_X0
0fdb: 18                           clc
0fdc: 65 08                        adc     ]col_ctr
0fde: a8                           tay
0fdf: 8a                           txa
0fe0: 91 06                        sta     (]hptr),y
0fe2: e6 08                        inc     ]col_ctr
0fe4: a5 08                        lda     ]col_ctr
0fe6: c9 04                        cmp     #4                ;end of column?
0fe8: d0 e4                        bne     :ColLoop          ;not yet
0fea: e6 1b                        inc     ]row_ctr
0fec: a5 1b                        lda     ]row_ctr
0fee: c9 15                        cmp     #21               ;end of bitmap?
0ff0: d0 c3                        bne     :RowLoop          ;not yet
0ff2: 60                           rts

                   ********************************************************************************
                   * Handle CIRCLE,color,X0,Y0,radius,drawMode,fillFlag                           *
                   *                                                                              *
                   * Draws an outline or filled circle.                                           *
                   *                                                                              *
                   * On entry:                                                                    *
                   *   $1F: colorIndex (0=green, 1=orange, 2=purple, 3=blue, 4=white)             *
                   *   $F9,FA,FB: x0,y0 (center)                                                  *
                   *   $1B: radius                                                                *
                   *   $1C: drawMode (0=draw, 1=erase, 2=invert)                                  *
                   *   $FF: fillFlag (0=outline, nonzero=filled)                                  *
                   *                                                                              *
                   * (Note the color index also allows 4=white.)                                  *
                   ********************************************************************************
                   • Clear variables
                   ]y_val          .var    $19    {addr/1}
                   ]x_val          .var    $1a    {addr/1}
                   ]radius         .var    $1b    {addr/1}
                   ]d_val          .var    $1d    {addr/1}

0ff3: a5 1b        HandleCIRCLE    lda     ]radius           ;check radius
0ff5: d0 04                        bne     :NonzeroRadius
0ff7: 20 60 08                     jsr     HandleDOT         ;just draw a dot at X0,Y0
0ffa: 60                           rts

0ffb: 85 19        :NonzeroRadius  sta     ]y_val
0ffd: 49 ff                        eor     #$ff
0fff: 85 1d                        sta     ]d_val            ;should be d = 1 - rad
1001: e6 1d                        inc     ]d_val
1003: a9 00                        lda     #$00
1005: 85 1a                        sta     ]x_val
1007: a5 f9                        lda     ARG_X0
1009: 85 fc                        sta     ARG_X1
100b: a5 fa                        lda     ARG_X0+1
100d: 85 fd                        sta     ARG_X1+1
100f: a5 fb                        lda     ARG_Y0
1011: 85 fe                        sta     ARG_Y1
                   ; Draw a pair of points or a horizontal line for all four quadrants.
1013: a5 fc        :CircleLoop     lda     ARG_X1
1015: 38                           sec
1016: e5 1a                        sbc     ]x_val
1018: 85 f9                        sta     ARG_X0
101a: a5 fd                        lda     ARG_X1+1
101c: e9 00                        sbc     #$00
101e: 85 fa                        sta     ARG_X0+1
1020: a5 fe                        lda     ARG_Y1
1022: 38                           sec
1023: e5 19                        sbc     ]y_val
1025: 85 fb                        sta     ARG_Y0
1027: 20 c1 10                     jsr     PushXY
102a: a5 fc                        lda     ARG_X1
102c: 18                           clc
102d: 65 1a                        adc     ]x_val
102f: 85 f9                        sta     ARG_X0
1031: a5 fd                        lda     ARG_X1+1
1033: 69 00                        adc     #$00
1035: 85 fa                        sta     ARG_X0+1
1037: 20 d1 10                     jsr     DrawPair          ;first
103a: a5 fe                        lda     ARG_Y1
103c: 18                           clc
103d: 65 19                        adc     ]y_val
103f: 85 fb                        sta     ARG_Y0
1041: 20 c1 10                     jsr     PushXY
1044: a5 fc                        lda     ARG_X1
1046: 38                           sec
1047: e5 1a                        sbc     ]x_val
1049: 85 f9                        sta     ARG_X0
104b: a5 fd                        lda     ARG_X1+1
104d: e9 00                        sbc     #$00
104f: 85 fa                        sta     ARG_X0+1
1051: 20 d1 10                     jsr     DrawPair          ;second
1054: a5 fc                        lda     ARG_X1
1056: 18                           clc
1057: 65 19                        adc     ]y_val
1059: 85 f9                        sta     ARG_X0
105b: a5 fd                        lda     ARG_X1+1
105d: 69 00                        adc     #$00
105f: 85 fa                        sta     ARG_X0+1
1061: a5 fe                        lda     ARG_Y1
1063: 38                           sec
1064: e5 1a                        sbc     ]x_val
1066: 85 fb                        sta     ARG_Y0
1068: 20 c1 10                     jsr     PushXY
106b: a5 fc                        lda     ARG_X1
106d: 38                           sec
106e: e5 19                        sbc     ]y_val
1070: 85 f9                        sta     ARG_X0
1072: a5 fd                        lda     ARG_X1+1
1074: e9 00                        sbc     #$00
1076: 85 fa                        sta     ARG_X0+1
1078: 20 d1 10                     jsr     DrawPair          ;third
107b: a5 fe                        lda     ARG_Y1
107d: 18                           clc
107e: 65 1a                        adc     ]x_val
1080: 85 fb                        sta     ARG_Y0
1082: 20 c1 10                     jsr     PushXY
1085: a5 fc                        lda     ARG_X1
1087: 18                           clc
1088: 65 19                        adc     ]y_val
108a: 85 f9                        sta     ARG_X0
108c: a5 fd                        lda     ARG_X1+1
108e: 69 00                        adc     #$00
1090: 85 fa                        sta     ARG_X0+1
1092: 20 d1 10                     jsr     DrawPair          ;fourth
                   ; Do update.  The math here is not quite correct (compared to what Bresenham
                   ; does), which is why large circles look distorted.  For example, try
                   ; &CIRCLE,4,139,95,90,0,1.
1095: a5 1a                        lda     ]x_val            ;d += (x << 1)
1097: 0a                           asl     A
1098: 38                           sec
1099: 65 1d                        adc     ]d_val
109b: 85 1d                        sta     ]d_val
109d: e6 1a                        inc     ]x_val            ;x++
109f: a5 1d                        lda     ]d_val            ;d < 0?
10a1: 30 11                        bmi     :NegD             ;yes, branch
10a3: e6 1d                        inc     ]d_val            ;d += 2
10a5: e6 1d                        inc     ]d_val
10a7: 06 19                        asl     ]y_val            ;y *= 2 (temporarily)
10a9: a5 1d                        lda     ]d_val            ;d -= (y * 2)
10ab: 38                           sec
10ac: e5 19                        sbc     ]y_val
10ae: 85 1d                        sta     ]d_val
10b0: 46 19                        lsr     ]y_val            ;y /= 2
10b2: c6 19                        dec     ]y_val            ;y--
10b4: a5 1a        :NegD           lda     ]x_val            ;is x <= y?
10b6: 38                           sec
10b7: e5 19                        sbc     ]y_val
10b9: 90 03                        bcc     :Cont
10bb: f0 01                        beq     :Cont
10bd: 60                           rts

10be: 4c 13 10     :Cont           jmp     :CircleLoop

10c1: a5 f9        PushXY          lda     ARG_X0
10c3: 8d 56 14                     sta     saved_xlo
10c6: a5 fa                        lda     ARG_X0+1
10c8: 8d 57 14                     sta     saved_xhi
10cb: a5 fb                        lda     ARG_Y0
10cd: 8d 58 14                     sta     saved_y
10d0: 60                           rts

                   ; Draws a pair of dots or a horizontal line.  Used for circle drawing.
10d1: a5 f9        DrawPair        lda     ARG_X0
10d3: 8d 59 14                     sta     saved_x2l
10d6: a5 fa                        lda     ARG_X0+1
10d8: 8d 5a 14                     sta     saved_x2h
10db: a2 06                        ldx     #$06              ;save state
10dd: b5 f9        :SaveLoop       lda     ARG_X0,x
10df: 9d 5b 14                     sta     scratch0,x
10e2: ca                           dex
10e3: 10 f8                        bpl     :SaveLoop
10e5: a2 05                        ldx     #$05
10e7: b5 19        :SaveLoop2      lda     ]y_val,x
10e9: 9d 62 14                     sta     scratch5+2,x
10ec: ca                           dex
10ed: 10 f8                        bpl     :SaveLoop2
10ef: a5 1f                        lda     ARG_COLOR         ;check desired color
10f1: c9 04                        cmp     #$04              ;solid white?
10f3: 90 4c                        bcc     ColorCircle       ;no, draw with color calls
10f5: ad 56 14                     lda     saved_xlo         ;yes, draw white points or lines
10f8: 85 f9                        sta     ARG_X0
10fa: ad 57 14                     lda     saved_xhi
10fd: 85 fa                        sta     ARG_X0+1
10ff: ad 58 14                     lda     saved_y
1102: 85 fb                        sta     ARG_Y0
1104: a5 ff                        lda     ARG_FF            ;filled circle?
1106: d0 13                        bne     DrawCircleLine    ;yes, branch
1108: 20 60 08                     jsr     HandleDOT         ;no, just plot a dot
110b: ad 59 14                     lda     saved_x2l
110e: 85 f9                        sta     ARG_X0
1110: ad 5a 14                     lda     saved_x2h
1113: 85 fa                        sta     ARG_X0+1
1115: 20 60 08                     jsr     HandleDOT         ;and another dot
1118: 4c 2c 11                     jmp     RestoreCircleCoord

111b: a5 fb        DrawCircleLine  lda     ARG_Y0            ;horizontal line
111d: 85 fe                        sta     ARG_Y1
111f: ad 59 14                     lda     saved_x2l
1122: 85 fc                        sta     ARG_X1
1124: ad 5a 14                     lda     saved_x2h
1127: 85 fd                        sta     ARG_X1+1
1129: 20 d0 08                     jsr     HandleLINE
                   RestoreCircleCoord
112c: a2 06                        ldx     #$06
112e: bd 5b 14     :Loop           lda     scratch0,x
1131: 95 f9                        sta     ARG_X0,x
1133: ca                           dex
1134: 10 f8                        bpl     :Loop
1136: a2 05                        ldx     #$05
1138: bd 62 14     :Loop2          lda     scratch5+2,x
113b: 95 19                        sta     ]y_val,x
113d: ca                           dex
113e: 10 f8                        bpl     :Loop2
1140: 60                           rts

1141: 4e 5a 14     ColorCircle     lsr     saved_x2h         ;convert X from 0-279 to 0-139
1144: 6e 59 14                     ror     saved_x2l
1147: 4e 57 14                     lsr     saved_xhi
114a: 6e 56 14                     ror     saved_xlo
114d: ad 56 14                     lda     saved_xlo
1150: 85 f9                        sta     ARG_X0
1152: ad 58 14                     lda     saved_y
1155: 85 fb                        sta     ARG_Y0
1157: a5 ff                        lda     ARG_FF            ;filled circle?
1159: d0 0e                        bne     :FilledColor      ;no, draw a line
115b: 20 8a 11                     jsr     HandleCDOT        ;yes, draw a couple of dots
115e: ad 59 14                     lda     saved_x2l
1161: 85 f9                        sta     ARG_X0
1163: 20 8a 11                     jsr     HandleCDOT
1166: 4c 2c 11                     jmp     RestoreCircleCoord

1169: a5 fb        :FilledColor    lda     ARG_Y0
116b: 85 fe                        sta     ARG_Y1
116d: ad 59 14                     lda     saved_x2l
1170: 85 fc                        sta     ARG_X1
1172: 20 e7 11                     jsr     HandleCLINE
1175: 4c 2c 11                     jmp     RestoreCircleCoord

                   ********************************************************************************
                   * Handle PENGUIN,X0,Y0,drawMode                                                *
                   *                                                                              *
                   * Draws a penguin.  Seriously.                                                 *
                   *                                                                              *
                   *   $F9/FA/FB: x0,y0 (where X is 0-139)                                        *
                   *   $1C: drawMode (0=draw, 1=erase, 2=invert)                                  *
                   ********************************************************************************
1178: a9 36        HandlePENGUIN   lda     #<penguin_data
117a: 85 08                        sta     $08
117c: a9 14                        lda     #>penguin_data
117e: 85 09                        sta     $09
1180: a9 10                        lda     #$10
1182: 85 fc                        sta     ARG_X1
1184: 85 fd                        sta     ARG_X1+1          ;item count
1186: 20 43 0f                     jsr     FromPenguin
1189: 60                           rts

                   ********************************************************************************
                   * Handle CDOT,colorIndex,X0,Y0,drawMode                                        *
                   *                                                                              *
                   * On entry:                                                                    *
                   *   $1F: colorIndex (0=green, 1=orange, 2=purple, 3=blue)                      *
                   *   $F9/FA/FB: x0,y0 (where X is 0-139)                                        *
                   *   $1C: drawMode (0=draw, 1=erase, 2=invert)                                  *
                   *                                                                              *
                   * X/Y args are range-checked for validity.                                     *
                   ********************************************************************************
                   • Clear variables
                   ]hptr           .var    $06    {addr/2}

118a: a4 fb        HandleCDOT      ldy     ARG_Y0            ;range check Y coord
118c: c0 c0                        cpy     #192
118e: b0 4c                        bcs     :Done             ;no good
1190: b9 b6 17                     lda     hr_addr_lo,y      ;set up base address
1193: 85 06                        sta     ]hptr
1195: b9 76 18                     lda     hr_addr_hi,y
1198: 0d 85 14                     ora     hpage
119b: 85 07                        sta     ]hptr+1
119d: a6 f9        HandleCDOT_1    ldx     ARG_X0            ;range check X coord
119f: e0 8c                        cpx     #140
11a1: b0 39                        bcs     :Done
11a3: a5 1f                        lda     ARG_COLOR         ;get color index
11a5: c9 02                        cmp     #$02              ;>= 2?
11a7: 10 09                        bpl     :UseShifted       ;yes, use second table
11a9: bd 86 14                     lda     div35_1,x         ;0 or 1, use first table
11ac: a8                           tay
11ad: bd 12 15                     lda     mod35_1,x
11b0: d0 07                        bne     :Cont             ;(always)
11b2: bd 9e 15     :UseShifted     lda     div35_2,x
11b5: a8                           tay
11b6: bd 2a 16                     lda     mod35_2,x
                   ; Now Y=byte offset, X=pixel mask.
11b9: aa           :Cont           tax
11ba: a5 1f                        lda     ARG_COLOR         ;check low bit of color index
11bc: 4a                           lsr     A
11bd: 90 09                        bcc     L11C8             ;clear, so clear hi bit on screen
11bf: a9 80                        lda     #$80              ;set, so set hi bit on screen
11c1: 11 06                        ora     (]hptr),y
11c3: 91 06                        sta     (]hptr),y
11c5: 4c ce 11                     jmp     :DoDraw

11c8: a9 7f        L11C8           lda     #$7f
11ca: 31 06                        and     (]hptr),y
11cc: 91 06                        sta     (]hptr),y
11ce: 8a           :DoDraw         txa
11cf: a6 1c                        ldx     ARG_DRAW_MODE     ;drawMode
11d1: f0 0a                        beq     L11DD             ;draw
11d3: ca                           dex
11d4: d0 0c                        bne     L11E2             ;invert
11d6: 49 ff                        eor     #$ff              ;erase
11d8: 31 06                        and     (]hptr),y
11da: 91 06                        sta     (]hptr),y
11dc: 60           :Done           rts

11dd: 11 06        L11DD           ora     (]hptr),y
11df: 91 06                        sta     (]hptr),y
11e1: 60                           rts

11e2: 51 06        L11E2           eor     (]hptr),y
11e4: 91 06                        sta     (]hptr),y
11e6: 60                           rts

                   ********************************************************************************
                   * Handle CLINE,colorIndex,X0,Y0,X1,Y1,drawMode                                 *
                   *                                                                              *
                   * On entry:                                                                    *
                   *   $1F: colorIndex (0=green, 1=orange, 2=purple, 3=blue)                      *
                   *   $F9/FA/FB: x0,y0 (where X0 is 0-139)                                       *
                   *   $FC/FD/FE: x1,y1 (where x1 is 0-139)                                       *
                   *   $1C: drawMode (0=draw, 1=erase, 2=invert)                                  *
                   *                                                                              *
                   * On exit:                                                                     *
                   *   $F9/FA/FB holds 2nd coordinate (so you can chain calls)                    *
                   ********************************************************************************
                   • Clear variables
                   ]move_dir       .var    $08    {addr/1}
                   ]tmp_x          .var    $19    {addr/1}
                   ]tmp_y          .var    $1b    {addr/1}
                   ]delta_x        .var    $1e    {addr/1}
                   ]delta_y        .var    $ff    {addr/1}

11e7: a5 fc        HandleCLINE     lda     ARG_X1            ;save these for later
11e9: 8d 56 14                     sta     saved_xlo
11ec: a5 fe                        lda     ARG_Y1
11ee: 8d 57 14                     sta     saved_xhi
11f1: a5 fb                        lda     ARG_Y0            ;compute y0 - y1
11f3: 38                           sec
11f4: e5 fe                        sbc     ARG_Y1            ;is y0 < y1?
11f6: b0 05                        bcs     :NoYFlip          ;no, branch
11f8: a5 fe                        lda     ARG_Y1            ;compute y1 - y0
11fa: 38                           sec
11fb: e5 fb                        sbc     ARG_Y0
11fd: 85 ff        :NoYFlip        sta     ]delta_y
11ff: a5 fc        :ComputeDeltaX  lda     ARG_X1            ;compute x1 - x0
1201: 38                           sec
1202: e5 f9                        sbc     ARG_X0            ;is x1 < x0?
1204: b0 06                        bcs     :GotDelta         ;no, branch
1206: 20 08 13                     jsr     SwapXY            ;yes, swap so we're drawing from left to right
1209: 4c ff 11                     jmp     :ComputeDeltaX

120c: 85 1e        :GotDelta       sta     ]delta_x          ;check for special cases
120e: f0 0e                        beq     :Vertical
1210: a5 ff                        lda     ]delta_y
1212: f0 2a                        beq     :Horizontal
1214: a5 1e                        lda     ]delta_x          ;compare the deltas
1216: 38                           sec
1217: e5 ff                        sbc     ]delta_y
1219: b0 49                        bcs     :HorizDom         ;delta X > delta Y, horizontally dominant
121b: 4c b8 12                     jmp     :VertDom

121e: 20 8a 11     :Vertical       jsr     HandleCDOT        ;draw a dot
1221: a5 ff                        lda     ]delta_y          ;check line length
1223: d0 01                        bne     :DrawVert         ;nonzero, so draw line
1225: 60                           rts

1226: a5 fe        :DrawVert       lda     ARG_Y1            ;is y1 < y0?
1228: 38                           sec
1229: e5 fb                        sbc     ARG_Y0
122b: b0 03                        bcs     :VertLoop         ;no, we're good
122d: 20 08 13                     jsr     SwapXY            ;swap so y0 is on top
1230: e6 fb        :VertLoop       inc     ARG_Y0            ;inc since we already plotted one point
1232: 20 8a 11                     jsr     HandleCDOT        ;plot the next point
1235: a5 fb                        lda     ARG_Y0            ;are we done?
1237: c5 fe                        cmp     ARG_Y1
1239: d0 f5                        bne     :VertLoop         ;not yet
123b: 4c fd 12                     jmp     CopySavedToX0

123e: 20 8a 11     :Horizontal     jsr     HandleCDOT        ;draw a dot
1241: e6 f9        :HorizLoop      inc     ARG_X0            ;move right
1243: 20 9d 11                     jsr     HandleCDOT_1      ;draw another dot
1246: a5 f9                        lda     ARG_X0            ;are we done?
1248: c5 fc                        cmp     ARG_X1
124a: d0 f5                        bne     :HorizLoop        ;not yet
124c: 4c fd 12                     jmp     CopySavedToX0

124f: e6 f9        :Diagonal       inc     ARG_X0            ;always move right
1251: a5 fb                        lda     ARG_Y0            ;up or down
1253: 18                           clc
1254: 65 08                        adc     ]move_dir
1256: 85 fb                        sta     ARG_Y0
1258: 20 8a 11                     jsr     HandleCDOT        ;draw a dot
125b: a5 fb                        lda     ARG_Y0            ;done?
125d: c5 fe                        cmp     ARG_Y1
125f: d0 ee                        bne     :Diagonal         ;not yet
1261: 4c fd 12                     jmp     CopySavedToX0

1264: 20 8a 11     :HorizDom       jsr     HandleCDOT        ;draw a dot
1267: a5 1e                        lda     ]delta_x
1269: 85 19                        sta     ]tmp_x
126b: a5 fe                        lda     ARG_Y1            ;check for pure horizontal
126d: 38                           sec
126e: e5 fb                        sbc     ARG_Y0
1270: f0 cf                        beq     :HorizLoop        ;yup, go do that
1272: 90 06                        bcc     :HorizUpward      ;which direction are we moving?
1274: a9 01                        lda     #$01              ;downward
1276: 85 08                        sta     ]move_dir
1278: d0 04                        bne     L127E

127a: a9 ff        :HorizUpward    lda     #$ff              ;upward
127c: 85 08                        sta     ]move_dir
127e: a5 1e        L127E           lda     ]delta_x          ;check for diagonal
1280: c5 ff                        cmp     ]delta_y
1282: f0 cb                        beq     :Diagonal         ;yup, go do that
1284: a5 1e                        lda     ]delta_x          ;update deltas
1286: 38                           sec
1287: e5 ff                        sbc     ]delta_y
1289: 85 1e                        sta     ]delta_x
128b: a5 1e        :HorizDomLoop   lda     ]delta_x
128d: 38                           sec
128e: e5 ff                        sbc     ]delta_y
1290: 85 1e                        sta     ]delta_x
1292: 90 08                        bcc     :UpdateY          ;need to update the Y coord, branch
1294: e6 f9                        inc     ARG_X0            ;just update X this time
1296: 20 9d 11                     jsr     HandleCDOT_1      ;draw
1299: 4c af 12                     jmp     :HorizCont

129c: a5 1e        :UpdateY        lda     ]delta_x          ;update deltas
129e: 18                           clc
129f: 65 19                        adc     ]tmp_x
12a1: 85 1e                        sta     ]delta_x
12a3: a5 fb                        lda     ARG_Y0            ;update Y coord
12a5: 18                           clc
12a6: 65 08                        adc     ]move_dir
12a8: 85 fb                        sta     ARG_Y0
12aa: e6 f9                        inc     ARG_X0            ;move right
12ac: 20 8a 11                     jsr     HandleCDOT        ;draw
12af: a5 f9        :HorizCont      lda     ARG_X0            ;are we done?
12b1: c5 fc                        cmp     ARG_X1
12b3: d0 d6                        bne     :HorizDomLoop     ;not yet
12b5: 4c fd 12                     jmp     CopySavedToX0

12b8: a5 fe        :VertDom        lda     ARG_Y1            ;is y1 > y0?
12ba: 38                           sec
12bb: e5 fb                        sbc     ARG_Y0
12bd: b0 09                        bcs     :XRight           ;yes, all is well
12bf: 20 08 13                     jsr     SwapXY            ;nope, swap so y0 is on top
12c2: a9 ff                        lda     #$ff              ;we were setup for left-to-right; now X will move
12c4: 85 08                        sta     ]move_dir         ; left on each step
12c6: 30 04                        bmi     :GotMove          ;(always)

12c8: a9 01        :XRight         lda     #$01              ;move X to the right
12ca: 85 08                        sta     ]move_dir
12cc: a5 ff        :GotMove        lda     ]delta_y
12ce: 85 1b                        sta     ]tmp_y
12d0: 85 19                        sta     ]tmp_x
12d2: 38                           sec
12d3: e5 1e                        sbc     ]delta_x
12d5: 85 ff                        sta     ]delta_y
12d7: 20 8a 11                     jsr     HandleCDOT        ;draw
12da: a5 ff        :VertDomLoop    lda     ]delta_y          ;update deltas
12dc: 38                           sec
12dd: e5 1e                        sbc     ]delta_x
12df: 85 ff                        sta     ]delta_y
12e1: b0 0e                        bcs     :DoDraw           ;just move Y, branch
12e3: a5 ff                        lda     ]delta_y          ;time to move X
12e5: 18                           clc
12e6: 65 19                        adc     ]tmp_x
12e8: 85 ff                        sta     ]delta_y
12ea: a5 f9                        lda     ARG_X0
12ec: 18                           clc
12ed: 65 08                        adc     ]move_dir
12ef: 85 f9                        sta     ARG_X0
12f1: e6 fb        :DoDraw         inc     ARG_Y0            ;move down
12f3: 20 8a 11                     jsr     HandleCDOT        ;draw
12f6: c6 1b                        dec     ]tmp_y            ;done?
12f8: d0 e0                        bne     :VertDomLoop      ;not yet
12fa: 4c fd 12                     jmp     CopySavedToX0

                   ; Copies the saved copy of X1/Y1 into X0/Y0.
12fd: ad 56 14     CopySavedToX0   lda     saved_xlo
1300: 85 f9                        sta     ARG_X0
1302: ad 57 14                     lda     saved_xhi
1305: 85 fb                        sta     ARG_Y0
1307: 60                           rts

                   ; Swap X0,Y0 with X1,Y1, ignoring X0H/X1H.
1308: a5 f9        SwapXY          lda     ARG_X0
130a: a6 fc                        ldx     ARG_X1
130c: 86 f9                        stx     ARG_X0
130e: 85 fc                        sta     ARG_X1
1310: a5 fb                        lda     ARG_Y0
1312: a4 fe                        ldy     ARG_Y1
1314: 84 fb                        sty     ARG_Y0
1316: 85 fe                        sta     ARG_Y1
1318: 60                           rts

                   ********************************************************************************
                   * Handle CBOX,colorIndex,X0,Y0,X1,Y1,drawMode,fillFlag                         *
                   *                                                                              *
                   * On entry:                                                                    *
                   *   $1F: colorIndex (0=green, 1=orange, 2=purple, 3=blue)                      *
                   *   $F9/FA/FB: x0,y0                                                           *
                   *   $FC/FD/FE: x1,y1                                                           *
                   *   $1C: drawMode (0=draw, 1=erase, 2=invert)                                  *
                   *   $FF: fill flag (0=outline, nonzero=filled)                                 *
                   ********************************************************************************
1319: a5 ff        HandleCBOX      lda     ]delta_y          ;check fill flag
131b: d0 41                        bne     FillCBOX          ;go do filled version
131d: a5 f9                        lda     ARG_X0
131f: 8d 5b 14                     sta     scratch0
1322: a5 fe                        lda     ARG_Y1
1324: 8d 5e 14                     sta     scratch3
1327: a5 fb                        lda     ARG_Y0
1329: 8d 5d 14                     sta     scratch2
132c: 85 fe                        sta     ARG_Y1
132e: a5 fc                        lda     ARG_X1
1330: 8d 5f 14                     sta     scratch4
1333: 20 e7 11                     jsr     HandleCLINE       ;draw x0,y0 to x1,y0
1336: ad 5f 14                     lda     scratch4
1339: 85 fc                        sta     ARG_X1
133b: ad 5e 14                     lda     scratch3
133e: 85 fe                        sta     ARG_Y1
1340: 20 e7 11                     jsr     HandleCLINE       ;draw x1,y0 to x1,y1
1343: ad 5e 14                     lda     scratch3
1346: 85 fe                        sta     ARG_Y1
1348: ad 5b 14                     lda     scratch0
134b: 85 fc                        sta     ARG_X1
134d: 20 e7 11                     jsr     HandleCLINE       ;draw x1,y1 to x0,y1
1350: ad 5b 14                     lda     scratch0
1353: 85 fc                        sta     ARG_X1
1355: ad 5d 14                     lda     scratch2
1358: 85 fe                        sta     ARG_Y1
135a: 20 e7 11                     jsr     HandleCLINE       ;draw x0,y1 to x0,y0
135d: 60                           rts

135e: a2 01        FillCBOX        ldx     #$01              ;up or down?
1360: a5 fe                        lda     ARG_Y1            ;is y1 < y0?
1362: 38                           sec
1363: e5 fb                        sbc     ARG_Y0
1365: b0 02                        bcs     :Y0Top            ;no, y0 on top, branch
1367: a2 ff                        ldx     #$ff              ;yes, move upward
1369: 8e 5d 14     :Y0Top          stx     scratch2
136c: a5 fe                        lda     ARG_Y1
136e: 8d 5e 14                     sta     scratch3
1371: a5 f9                        lda     ARG_X0
1373: 8d 5b 14                     sta     scratch0
1376: a5 fb                        lda     ARG_Y0
1378: 85 fe                        sta     ARG_Y1
137a: a5 fc                        lda     ARG_X1
137c: 8d 5f 14                     sta     scratch4
137f: 20 e7 11     :FillLoop       jsr     HandleCLINE       ;draw x0,y0 to x1,y0
1382: ad 5b 14                     lda     scratch0          ;restore x0/x1
1385: 85 f9                        sta     ARG_X0
1387: ad 5f 14                     lda     scratch4
138a: 85 fc                        sta     ARG_X1
138c: a5 fb                        lda     ARG_Y0            ;update y0/y1
138e: cd 5e 14                     cmp     scratch3          ;are we done?
1391: f0 0b                        beq     :Done
1393: 18                           clc
1394: 6d 5d 14                     adc     scratch2          ;move Y coords
1397: 85 fb                        sta     ARG_Y0            ;set both (horizontal line)
1399: 85 fe                        sta     ARG_Y1
139b: 4c 7f 13                     jmp     :FillLoop

139e: 60           :Done           rts

                   ********************************************************************************
                   * Handle CCHARSET,colorIndex,X0,Y0,itemIndex,dataPtr,drawMode                  *
                   *                                                                              *
                   * Draws a graphic from a compressed bitmap.                                    *
                   *                                                                              *
                   * On entry:                                                                    *
                   *   $1F: colorIndex                                                            *
                   *   $F9/FA/FB: x0,y0 (top left)                                                *
                   *   $1E: item index                                                            *
                   *   $E8/E9: pointer to image data set                                          *
                   *   $1C: drawMode (0=draw, 1=erase, 2=invert)                                  *
                   ********************************************************************************
                   • Clear variables
                   ]data_ptr       .var    $08    {addr/2}
                   ]data_offset    .var    $19    {addr/2}
                   ]width          .var    $fc    {addr/1}
                   ]height         .var    $fd    {addr/1}
                   ]row_ctr        .var    $ff    {addr/1}

139f: a6 1e        HandleCCHARSET  ldx     ARG_ITEM_INDEX    ;requested item index
13a1: a0 00                        ldy     #$00
13a3: b1 e8                        lda     (ARG_EXT_PTR),y   ;check table max
13a5: c5 1e                        cmp     ARG_ITEM_INDEX    ;is max >= our value?
13a7: b0 0a                        bcs     :IndexOkay        ;yes, branch
13a9: 20 dd fb                     jsr     MON_BELL1
13ac: 20 dd fb                     jsr     MON_BELL1
13af: 20 dd fb                     jsr     MON_BELL1
13b2: 60                           rts

13b3: 98           :IndexOkay      tya                       ;A=0
13b4: 86 08                        stx     ]data_ptr         ;store index
13b6: 85 09                        sta     ]data_ptr+1
13b8: 06 08                        asl     ]data_ptr         ;multiply by 4
13ba: 26 09                        rol     ]data_ptr+1
13bc: 06 08                        asl     ]data_ptr
13be: 26 09                        rol     ]data_ptr+1
13c0: a5 08                        lda     ]data_ptr         ;add the data ptr arg
13c2: 38                           sec
13c3: 65 e8                        adc     ARG_EXT_PTR
13c5: 85 08                        sta     ]data_ptr
13c7: a5 09                        lda     ]data_ptr+1
13c9: 65 e9                        adc     ARG_EXT_PTR+1
13cb: 85 09                        sta     ]data_ptr+1
                   ; Now data_ptr points at the item descriptor.
13cd: a0 00                        ldy     #$00
13cf: b1 08                        lda     (]data_ptr),y     ;get the offset
13d1: 85 19                        sta     ]data_offset
13d3: c8                           iny
13d4: b1 08                        lda     (]data_ptr),y
13d6: 85 1a                        sta     ]data_offset+1
13d8: c8                           iny
13d9: b1 08                        lda     (]data_ptr),y     ;width in pixels
13db: 85 fc                        sta     ]width
13dd: c8                           iny
13de: b1 08                        lda     (]data_ptr),y     ;height in pixels
13e0: 85 fd                        sta     ]height
13e2: a5 19                        lda     ]data_offset
13e4: 18                           clc
13e5: 65 e8                        adc     ARG_EXT_PTR       ;set data_ptr to the bitmap data
13e7: 85 08                        sta     ]data_ptr         ; by adding in the offset
13e9: a5 1a                        lda     ]data_offset+1
13eb: 65 e9                        adc     ARG_EXT_PTR+1
13ed: 85 09                        sta     ]data_ptr+1
                   ]hptr           .var    $06    {addr/2}
                   ]saved_x0       .var    $19    {addr/1}
                   ]bit_mask       .var    $1d    {addr/1}
                   ]col_ctr        .var    $fe    {addr/1}

13ef: a5 fd                        lda     ]height           ;init row counter
13f1: 85 ff                        sta     ]row_ctr
13f3: a9 01                        lda     #$01
13f5: 85 1d                        sta     ]bit_mask
13f7: a5 f9                        lda     ARG_X0
13f9: 85 19                        sta     ]saved_x0
13fb: a5 fc        :RowLoop        lda     ]width            ;init col counter
13fd: 85 fe                        sta     ]col_ctr
13ff: a4 fb                        ldy     ARG_Y0            ;get row
1401: b9 b6 17                     lda     hr_addr_lo,y      ;find hi-res row address
1404: 85 06                        sta     ]hptr
1406: b9 76 18                     lda     hr_addr_hi,y
1409: 0d 85 14                     ora     hpage
140c: 85 07                        sta     ]hptr+1
140e: a0 00        :ColLoop        ldy     #$00              ;get byte of pixel data
1410: b1 08                        lda     (]data_ptr),y
1412: 25 1d                        and     ]bit_mask         ;extract bit
1414: f0 03                        beq     :NoDraw           ;zero, don't draw
1416: 20 9d 11                     jsr     HandleCDOT_1      ;one, do draw
1419: 06 1d        :NoDraw         asl     ]bit_mask         ;advance to next bit
141b: 90 08                        bcc     :MoreBits         ;more bits, branch
141d: e6 1d                        inc     ]bit_mask         ;set mask to $01
141f: e6 08                        inc     ]data_ptr         ;advance to next byte
1421: d0 02                        bne     :MoreBits
1423: e6 09                        inc     ]data_ptr+1
1425: e6 f9        :MoreBits       inc     ARG_X0            ;move right
1427: c6 fe                        dec     ]col_ctr          ;more to do in this row?
1429: d0 e3                        bne     :ColLoop          ;yes, branch
142b: e6 fb                        inc     ARG_Y0            ;move down to next row
142d: a5 19                        lda     ]saved_x0         ;move back to left edge
142f: 85 f9                        sta     ARG_X0
1431: c6 ff                        dec     ]row_ctr          ;more to do?
1433: d0 c6                        bne     :RowLoop          ;yes?
1435: 60                           rts

                   ; Penguin image data for CHARSET (16x16).
                   vis
1436: e0 01 10 02+ penguin_data    .bulk   e00110028804083c080410021004500a500a5009c804040232064e08c00f0000
1456: b8           saved_xlo       .dd1    $b8
1457: a5           saved_xhi       .dd1    $a5
1458: b3           saved_y         .dd1    $b3
1459: c0           saved_x2l       .dd1    $c0
145a: c1           saved_x2h       .dd1    $c1
145b: a0           scratch0        .dd1    $a0
145c: 85           scratch1        .dd1    $85
145d: a0           scratch2        .dd1    $a0
145e: a2           scratch3        .dd1    $a2
145f: a0           scratch4        .dd1    $a0
1460: e7           scratch5        .dd1    $e7
1461: a0                           .dd1    $a0
1462: a0                           .dd1    $a0
1463: a5                           .dd1    $a5
1464: c5                           .dd1    $c5
1465: 83           scratch10       .dd1    $83
1466: c2                           .dd1    $c2
1467: e8                           .dd1    $e8
1468: a0                           .dd1    $a0
1469: a0           saved_1f        .dd1    $a0
146a: 01           angle_xsign     .dd1    $01
146b: 01                           .dd1    $01
146c: ff                           .dd1    $ff
146d: ff                           .dd1    $ff
146e: 01           angle_ysign     .dd1    $01
146f: ff                           .dd1    $ff
1470: ff                           .dd1    $ff
1471: 01                           .dd1    $01
                   ; Color values for CLR function.
1472: 00 2a 55 7f+ clr_color_table .bulk   002a557f80aad5ff  ;even columns
147a: 00 55 2a 7f+                 .bulk   00552a7f80d5aaff  ;odd columns
                   ; EOR values for SCFLIP
1482: 7f 80 ff     flip_pattern    .bulk   7f80ff
                   ; Hi-res page we're currently working on ($20 or $40).
1485: 20           hpage           .dd1    $20
                   ; 
                   ; Color X coordinate (0-139) divided by 3.5 to get byte column.
                   ; 
1486: 00 00 00 01+ div35_1         .bulk   0000000101010102020203030303040404050505050606060707070708080809
                                    +      0909090a0a0a0b0b0b0b0c0c0c0d0d0d0d0e0e0e0f0f0f0f1010101111111112
                                    +      1212131313131414141515151516161617171717181818191919191a1a1a1b1b
                                    +      1b1b1c1c1c1d1d1d1d1e1e1e1f1f1f1f20202021212121222222232323232424
                                    +      242525252526262627272727
                   ; 
                   ; Color X coordinate (0-139) mod 3.5 to get pixel value (green/orange).
                   ; 
1512: 02 08 20 01+ mod35_1         .bulk   0208200104104002082001041040020820010410400208200104104002082001
                                    +      0410400208200104104002082001041040020820010410400208200104104002
                                    +      0820010410400208200104104002082001041040020820010410400208200104
                                    +      1040020820010410400208200104104002082001041040020820010410400208
                                    +      200104104002082001041040
                   ; 
                   ; Like div35_1, but shifted over one bit.
                   ; 
159e: 00 00 00 00+ div35_2         .bulk   0000000001010102020202030303040404040505050606060607070708080808
                                    +      0909090a0a0a0a0b0b0b0c0c0c0c0d0d0d0e0e0e0e0f0f0f1010101011111112
                                    +      1212121313131414141415151516161616171717181818181919191a1a1a1a1b
                                    +      1b1b1c1c1c1c1d1d1d1e1e1e1e1f1f1f20202020212121222222222323232424
                                    +      242425252526262626272727
                   ; 
                   ; Like mod35_1, but shifted over 1 bit (purple/blue).
                   ; 
162a: 01 04 10 40+ mod35_2         .bulk   0104104002082001041040020820010410400208200104104002082001041040
                                    +      0208200104104002082001041040020820010410400208200104104002082001
                                    +      0410400208200104104002082001041040020820010410400208200104104002
                                    +      0820010410400208200104104002082001041040020820010410400208200104
                                    +      104002082001041040020820
                   ; 
                   ; Sine/cosine values for LINESET angle.
                   ; 
16b6: 00 06 0c 12+ angle_sin       .bulk   00060c12181f252b31373d444a4f555b61676d72787d83888d92979ca1a6abaf
                                    +      b4b8bcc1c5c9ccd0d4d7dadde0e3e6e9ebedf0f2f4f5f7f8fafbfcfdfdfefefe
                                    +      fefefefefdfdfcfbfaf8f7f5f4f2f0edebe9e6e3e0dddad7d4d0ccc9c5c1bcb8
                                    +      b4afaba6a19c97928d88837d78726d67615b554f4a443d37312b251f18120c06
1736: fe fe fe fe+ angle_cos       .bulk   fefefefefdfdfcfbfaf8f7f5f4f2f0edebe9e6e3e0dddad7d4d0ccc9c5c1bcb8
                                    +      b4afaba6a19c97928d88837d78726d67615b554f4a443d37312b251f18120c06
                                    +      00060c12181f252b31373d444a4f555b61676d72787d83888d92979ca1a6abaf
                                    +      b4b8bcc1c5c9ccd0d4d7dadde0e3e6e9ebedf0f2f4f5f7f8fafbfcfdfdfefefe
                   ; 
                   ; Hi-res row base addresses.
                   ; 
                   ; The high byte doesn't have the page number included.
                   ; 
17b6: 00 00 00 00+ hr_addr_lo      .bulk   0000000000000000808080808080808000000000000000008080808080808080
                                    +      0000000000000000808080808080808000000000000000008080808080808080
                                    +      2828282828282828a8a8a8a8a8a8a8a82828282828282828a8a8a8a8a8a8a8a8
                                    +      2828282828282828a8a8a8a8a8a8a8a82828282828282828a8a8a8a8a8a8a8a8
                                    +      5050505050505050d0d0d0d0d0d0d0d05050505050505050d0d0d0d0d0d0d0d0
                                    +      5050505050505050d0d0d0d0d0d0d0d05050505050505050d0d0d0d0d0d0d0d0
1876: 00 04 08 0c+ hr_addr_hi      .bulk   0004080c1014181c0004080c1014181c0105090d1115191d0105090d1115191d
                                    +      02060a0e12161a1e02060a0e12161a1e03070b0f13171b1f03070b0f13171b1f
                                    +      0004080c1014181c0004080c1014181c0105090d1115191d0105090d1115191d
                                    +      02060a0e12161a1e02060a0e12161a1e03070b0f13171b1f03070b0f13171b1f
                                    +      0004080c1014181c0004080c1014181c0105090d1115191d0105090d1115191d
                                    +      02060a0e12161a1e02060a0e12161a1e03070b0f13171b1f03070b0f13171b1f
                   ; 
                   ; Convert X coordinate (0-255) to hi-res column byte by dividing by 7.
                   ; 
1936: 00 00 00 00+ div7_lo         .bulk   0000000000000001010101010101020202020202020303030303030304040404
                                    +      0404040505050505050506060606060606070707070707070808080808080809
                                    +      0909090909090a0a0a0a0a0a0a0b0b0b0b0b0b0b0c0c0c0c0c0c0c0d0d0d0d0d
                                    +      0d0d0e0e0e0e0e0e0e0f0f0f0f0f0f0f10101010101010111111111111111212
                                    +      1212121212131313131313131414141414141415151515151515161616161616
                                    +      161717171717171718181818181818191919191919191a1a1a1a1a1a1a1b1b1b
                                    +      1b1b1b1b1c1c1c1c1c1c1c1d1d1d1d1d1d1d1e1e1e1e1e1e1e1f1f1f1f1f1f1f
                                    +      2020202020202021212121212121222222222222222323232323232324242424
                   ; 
                   ; Convert X coordinate (256-279) to hi-res column by dividing by 7.
                   ; 
1a36: 24 24 24 25+ div7_hi         .bulk   242424252525252525252626262626262627272727272727
                   ; 
                   ; Compute pixel mask for X coordinate (0-255).
                   ; 
1a4e: 01 02 04 08+ mod7_lo         .bulk   0102040810204001020408102040010204081020400102040810204001020408
                                    +      1020400102040810204001020408102040010204081020400102040810204001
                                    +      0204081020400102040810204001020408102040010204081020400102040810
                                    +      2040010204081020400102040810204001020408102040010204081020400102
                                    +      0408102040010204081020400102040810204001020408102040010204081020
                                    +      4001020408102040010204081020400102040810204001020408102040010204
                                    +      0810204001020408102040010204081020400102040810204001020408102040
                                    +      0102040810204001020408102040010204081020400102040810204001020408
                   ; 
                   ; Compute pixel mask for X coordinate (256-279).
                   ; 
1b4e: 10 20 40 01+ mod7_hi         .bulk   102040010204081020400102040810204001020408102040
                   ; 
                   ; The remaining items don't actually seem to be used.
                   ; 
1b66: d0 05 ad 00+                 .junk   8
1b6e: 3a 20 53 59+                 .str    ‘: SYNTAX’
1b76: 8d                           .dd1    $8d
1b77: 3a 20 42 41+                 .str    ‘: BAD FORMAT’
1b83: 8d                           .dd1    $8d
1b84: 3a 20 4d 45+                 .str    ‘: MEMORY FULL’
1b91: 8d                           .dd1    $8d
1b92: 3a 20 42 41+                 .str    ‘: BAD RANGE’
1b9d: 8d                           .dd1    $8d
1b9e: 42 59 54 45+                 .str    ‘BYTES USED’
1ba8: 8d                           .dd1    $8d
1ba9: 42 59 54 45+                 .str    ‘BYTES REMAINING’
1bb8: 8d                           .dd1    $8d
1bb9: 41 4c 4c 20+                 .str    ‘ALL OR SOME?(A/S)?’
1bcb: 8d                           .dd1    $8d
1bcc: 3a 20 42 41+                 .str    ‘: BAD SLOT OR DRIVE ’

Symbol Table

BDRW$0821
BOX$0818
CBOX$0833
CCHARSET$0836
CDOT$082a
CHARSET$081e
CHKDOT$0806
CIRCLE$0824
CLINE$0830
CLR$080f
DISPPG1$0858
DISPPG2$085c
DOT$0800
DRWPG1$084c
DRWPG2$0852
HIRES_$0839
HISCROLL$0815
HROFF$0840
LINE$0809
LINESET$080c
PENGUIN$0827
SCFLIP$0812
SWITCHC$081b
WINDOW$0844
WNDOFF$0848